<!DOCTYPE html>
<html lang="zh-Hans">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 5.4.0">


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.15.4/css/all.min.css" integrity="sha256-mUZM63G8m73Mcidfrv5E+Y61y7a12O5mW4ezU3bxqW4=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/animate.css@3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">

<script class="next-config" data-name="main" type="application/json">{"hostname":"chenwingsing.github.io","root":"/","images":"/images","scheme":"Mist","darkmode":false,"version":"8.8.2","exturl":false,"sidebar":{"position":"right","display":"post","padding":18,"offset":12},"copycode":false,"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":"valine","storage":true,"lazyload":false,"nav":null,"activeClass":"valine"},"stickytabs":false,"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"}}</script><script src="/js/config.js"></script>
<meta name="description" content="按照《Leetcode101-A Leetcode Gringding Guide》顺序记录。除此之外，开始正视代码书写规范。">
<meta property="og:type" content="article">
<meta property="og:title" content="LeetCode-JAVA">
<meta property="og:url" content="https://chenwingsing.github.io/2021/09/20/LeetCode-JAVA/index.html">
<meta property="og:site_name" content="小陈同学">
<meta property="og:description" content="按照《Leetcode101-A Leetcode Gringding Guide》顺序记录。除此之外，开始正视代码书写规范。">
<meta property="og:locale">
<meta property="og:image" content="https://chenwingsing.github.io/images/leetcode-java/4.jpg">
<meta property="og:image" content="https://chenwingsing.github.io/images/leetcode-java/4-4.jpg">
<meta property="og:image" content="https://chenwingsing.github.io/images/leetcode-java/5-4-1.png">
<meta property="og:image" content="https://chenwingsing.github.io/images/leetcode-java/5-4-2.png">
<meta property="og:image" content="https://chenwingsing.github.io/images/leetcode-java/5-5.png">
<meta property="article:published_time" content="2021-09-20T02:48:01.000Z">
<meta property="article:modified_time" content="2022-01-01T14:33:01.832Z">
<meta property="article:author" content="小陈同学">
<meta property="article:tag" content="Leetcode">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://chenwingsing.github.io/images/leetcode-java/4.jpg">


<link rel="canonical" href="https://chenwingsing.github.io/2021/09/20/LeetCode-JAVA/">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"zh-Hans","comments":true,"permalink":"https://chenwingsing.github.io/2021/09/20/LeetCode-JAVA/","path":"2021/09/20/LeetCode-JAVA/","title":"LeetCode-JAVA"}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>LeetCode-JAVA | 小陈同学</title>
  




  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
<link rel="alternate" href="/atom.xml" title="小陈同学" type="application/atom+xml">
</head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <p class="site-title">小陈同学</p>
      <i class="logo-line"></i>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu">
        <li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a></li>
        <li class="menu-item menu-item-books"><a href="/books/" rel="section"><i class="fa fa-book fa-fw"></i>书籍</a></li>
        <li class="menu-item menu-item-archives"><a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a></li>
        <li class="menu-item menu-item-about"><a href="/about/" rel="section"><i class="fa fa-user fa-fw"></i>关于</a></li>
  </ul>
</nav>




</div>
        
  
  <div class="toggle sidebar-toggle" role="button">
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
  </div>

  <aside class="sidebar">

    <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
            <div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#%E8%B4%AA%E5%BF%83%E7%AE%97%E6%B3%95"><span class="nav-number">1.</span> <span class="nav-text">贪心算法</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#445-%E5%88%86%E5%8F%91%E9%A5%BC%E5%B9%B2-easy"><span class="nav-number">1.1.</span> <span class="nav-text">445 分发饼干 easy</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#135-%E5%88%86%E5%8F%91%E7%B3%96%E6%9E%9C-hard"><span class="nav-number">1.2.</span> <span class="nav-text">135 分发糖果 hard</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#435-%E6%97%A0%E9%87%8D%E5%8F%A0%E5%8C%BA%E9%97%B4-medium-%E5%8F%AF%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92"><span class="nav-number">1.3.</span> <span class="nav-text">435 无重叠区间 medium(可动态规划)</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#605-%E7%A7%8D%E8%8A%B1%E9%97%AE%E9%A2%98-easy"><span class="nav-number">1.4.</span> <span class="nav-text">605 种花问题 easy</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#452-%E7%94%A8%E6%9C%80%E5%B0%91%E6%95%B0%E9%87%8F%E7%9A%84%E7%AE%AD%E5%BC%95%E7%88%86%E6%B0%94%E7%90%83-medium-%E5%92%8C435%E7%9B%B8%E4%BC%BC"><span class="nav-number">1.5.</span> <span class="nav-text">452 用最少数量的箭引爆气球 medium(和435相似)</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#763-%E5%88%92%E5%88%86%E5%AD%97%E6%AF%8D%E5%8C%BA%E9%97%B4-medium"><span class="nav-number">1.6.</span> <span class="nav-text">763 划分字母区间 medium</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#122-%E4%B9%B0%E5%8D%96%E8%82%A1%E7%A5%A8%E7%9A%84%E6%9C%80%E4%BD%B3%E6%97%B6%E6%9C%BA2-easy-%E5%8F%AF%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92"><span class="nav-number">1.7.</span> <span class="nav-text">122 买卖股票的最佳时机2 easy(可动态规划)</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#406-%E6%A0%B9%E6%8D%AE%E8%BA%AB%E9%AB%98%E9%87%8D%E5%BB%BA%E9%98%9F%E5%88%97-medium"><span class="nav-number">1.8.</span> <span class="nav-text">406 根据身高重建队列 medium</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#665-%E9%9D%9E%E9%80%92%E5%87%8F%E6%95%B0%E5%88%97-easy"><span class="nav-number">1.9.</span> <span class="nav-text">665 非递减数列 easy</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E5%8F%8C%E6%8C%87%E9%92%88"><span class="nav-number">2.</span> <span class="nav-text">双指针</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#167-%E4%B8%A4%E6%95%B0%E4%B9%8B%E5%92%8C2-easy"><span class="nav-number">2.1.</span> <span class="nav-text">167 两数之和2 easy</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#88-%E5%90%88%E5%B9%B6%E4%B8%A4%E4%B8%AA%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84-easy"><span class="nav-number">2.2.</span> <span class="nav-text">88 合并两个有序数组 easy</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#142-%E7%8E%AF%E5%BD%A2%E9%93%BE%E8%A1%A82-medium"><span class="nav-number">2.3.</span> <span class="nav-text">142 环形链表2 medium</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#76-%E6%9C%80%E5%B0%8F%E8%A6%86%E7%9B%96%E5%AD%90%E4%B8%B2-hard"><span class="nav-number">2.4.</span> <span class="nav-text">76 最小覆盖子串 hard</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#633-%E5%B9%B3%E6%96%B9%E6%95%B0%E4%B9%8B%E5%92%8C-medium"><span class="nav-number">2.5.</span> <span class="nav-text">633 平方数之和 medium</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#680-%E9%AA%8C%E8%AF%81%E5%9B%9E%E6%96%87%E5%AD%97%E7%AC%A6%E4%B8%B22-easy"><span class="nav-number">2.6.</span> <span class="nav-text">680 验证回文字符串2 easy</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#524-%E9%80%9A%E8%BF%87%E5%88%A0%E9%99%A4%E5%AD%97%E6%AF%8D%E5%8C%B9%E9%85%8D%E5%88%B0%E5%AD%97%E5%85%B8%E9%87%8C%E6%9C%80%E9%95%BF%E5%8D%95%E8%AF%8D-medium"><span class="nav-number">2.7.</span> <span class="nav-text">524 通过删除字母匹配到字典里最长单词 medium</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE"><span class="nav-number">3.</span> <span class="nav-text">二分查找</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#69-Sqrt-x-easy"><span class="nav-number">3.1.</span> <span class="nav-text">69 Sqrt(x) easy</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#34-%E5%9C%A8%E6%8E%92%E5%BA%8F%E6%95%B0%E7%BB%84%E4%B8%AD%E6%9F%A5%E6%89%BE%E5%85%83%E7%B4%A0%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AA%E5%92%8C%E6%9C%80%E5%90%8E%E4%B8%80%E4%B8%AA%E4%BD%8D%E7%BD%AE-medium"><span class="nav-number">3.2.</span> <span class="nav-text">34 在排序数组中查找元素的第一个和最后一个位置 medium</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#81-%E6%90%9C%E7%B4%A2%E6%97%8B%E8%BD%AC%E6%8E%92%E5%BA%8F%E6%95%B0%E7%BB%84-II-medium"><span class="nav-number">3.3.</span> <span class="nav-text">81 搜索旋转排序数组 II medium</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#154-%E5%AF%BB%E6%89%BE%E6%97%8B%E8%BD%AC%E6%8E%92%E5%BA%8F%E6%95%B0%E7%BB%84%E4%B8%AD%E7%9A%84%E6%9C%80%E5%B0%8F%E5%80%BC-II-hard"><span class="nav-number">3.4.</span> <span class="nav-text">154 寻找旋转排序数组中的最小值 II hard</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#540-%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E4%B8%AD%E7%9A%84%E5%8D%95%E4%B8%80%E5%85%83%E7%B4%A0-meidum"><span class="nav-number">3.5.</span> <span class="nav-text">540. 有序数组中的单一元素 meidum</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#4-%E5%AF%BB%E6%89%BE%E4%B8%A4%E4%B8%AA%E6%AD%A3%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E4%B8%AD%E4%BD%8D%E6%95%B0-hard"><span class="nav-number">3.6.</span> <span class="nav-text">4 寻找两个正序数组的中位数 hard</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E5%B8%B8%E7%94%A8%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95"><span class="nav-number">4.</span> <span class="nav-text">常用排序算法</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%BF%AB%E9%80%9F%E6%8E%92%E5%BA%8F"><span class="nav-number">4.1.</span> <span class="nav-text">快速排序</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%8F%92%E5%85%A5%E6%8E%92%E5%BA%8F"><span class="nav-number">4.2.</span> <span class="nav-text">插入排序</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%80%89%E6%8B%A9%E6%8E%92%E5%BA%8F"><span class="nav-number">4.3.</span> <span class="nav-text">选择排序</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%BD%92%E5%B9%B6%E6%8E%92%E5%BA%8F"><span class="nav-number">4.4.</span> <span class="nav-text">归并排序</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%86%92%E6%B3%A1%E6%8E%92%E5%BA%8F"><span class="nav-number">4.5.</span> <span class="nav-text">冒泡排序</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#215-%E6%95%B0%E7%BB%84%E4%B8%AD%E7%9A%84%E7%AC%ACK%E4%B8%AA%E6%9C%80%E5%A4%A7%E5%85%83%E7%B4%A0-medium"><span class="nav-number">4.6.</span> <span class="nav-text">215 数组中的第K个最大元素 medium</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#347-%E5%89%8DK%E4%B8%AA%E9%AB%98%E9%A2%91%E5%85%83%E7%B4%A0-%E6%A1%B6%E6%8E%92%E5%BA%8F-medium"><span class="nav-number">4.7.</span> <span class="nav-text">347 前K个高频元素(桶排序) medium</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#451-%E6%A0%B9%E6%8D%AE%E5%AD%97%E7%AC%A6%E5%87%BA%E7%8E%B0%E9%A2%91%E7%8E%87%E6%8E%92%E5%BA%8F-%E6%A1%B6%E6%8E%92%E5%BA%8F-medium"><span class="nav-number">4.8.</span> <span class="nav-text">451 根据字符出现频率排序(桶排序) medium</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#75-%E9%A2%9C%E8%89%B2%E5%88%86%E7%B1%BB-medium"><span class="nav-number">4.9.</span> <span class="nav-text">75 颜色分类 medium</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%B8%80%E5%88%87%E7%9A%86%E5%8F%AF%E6%90%9C%E7%B4%A2"><span class="nav-number">5.</span> <span class="nav-text">一切皆可搜索</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#695-%E5%B2%9B%E5%B1%BF%E7%9A%84%E6%9C%80%E5%A4%A7%E9%9D%A2%E7%A7%AF-DFS-medium"><span class="nav-number">5.1.</span> <span class="nav-text">695 岛屿的最大面积(DFS) medium</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#547-%E7%9C%81%E4%BB%BD%E6%95%B0%E9%87%8F-DFS-medium"><span class="nav-number">5.2.</span> <span class="nav-text">547 省份数量(DFS) medium</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#417-%E5%A4%AA%E5%B9%B3%E6%B4%8B%E5%A4%A7%E8%A5%BF%E6%B4%8B%E6%B0%B4%E6%B5%81%E9%97%AE%E9%A2%98-DFS-medium"><span class="nav-number">5.3.</span> <span class="nav-text">!417 太平洋大西洋水流问题(DFS) medium</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#46-%E5%85%A8%E6%8E%92%E5%88%97-%E5%9B%9E%E6%BA%AF%E6%B3%95-medium"><span class="nav-number">5.4.</span> <span class="nav-text">46 全排列(回溯法) medium</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#77-%E7%BB%84%E5%90%88-%E5%9B%9E%E6%BA%AF%E6%B3%95-medium"><span class="nav-number">5.5.</span> <span class="nav-text">77 组合(回溯法) medium</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#79-%E5%8D%95%E8%AF%8D%E6%90%9C%E7%B4%A2-%E5%9B%9E%E6%BA%AF%E6%B3%95-medium"><span class="nav-number">5.6.</span> <span class="nav-text">79 单词搜索(回溯法) medium</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#51-N%E7%9A%87%E5%90%8E-%E5%9B%9E%E6%BA%AF%E6%B3%95-hard"><span class="nav-number">5.7.</span> <span class="nav-text">51 N皇后(回溯法) hard</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#934-%E6%9C%80%E7%9F%AD%E7%9A%84%E6%A1%A5-DFS-BFS-medium"><span class="nav-number">5.8.</span> <span class="nav-text">934 最短的桥(DFS+BFS) medium</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#126-%E5%8D%95%E8%AF%8D%E6%8E%A5%E9%BE%992-%E5%9B%9E%E6%BA%AF-BFS-hard"><span class="nav-number">5.9.</span> <span class="nav-text">126 单词接龙2(回溯+BFS) hard</span></a></li></ol></li></ol></div>
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author site-overview-item animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <p class="site-author-name" itemprop="name">小陈同学</p>
  <div class="site-description" itemprop="description">求知若饥，虚心若愚</div>
</div>
<div class="site-state-wrap site-overview-item animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">19</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
          <a href="/categories/">
        <span class="site-state-item-count">8</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
          <a href="/tags/">
        <span class="site-state-item-count">14</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>
  <div class="links-of-author site-overview-item animated">
      <span class="links-of-author-item">
        <a href="https://github.com/chenwingsing" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;chenwingsing" rel="noopener" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
      </span>
      <span class="links-of-author-item">
        <a href="mailto:chen_yongcheng@outlook.com" title="E-Mail → mailto:chen_yongcheng@outlook.com" rel="noopener" target="_blank"><i class="fa fa-envelope fa-fw"></i>E-Mail</a>
      </span>
      <span class="links-of-author-item">
        <a href="/atom.xml" title="RSS → &#x2F;atom.xml"><i class="fa fa-rss fa-fw"></i>RSS</a>
      </span>
  </div>



        </div>
      </div>
    </div>
  </aside>
  <div class="sidebar-dimmer"></div>


    </header>

    
  <div class="back-to-top" role="button" aria-label="返回顶部">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


    <div class="main-inner post posts-expand">


  


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-Hans">
    <link itemprop="mainEntityOfPage" href="https://chenwingsing.github.io/2021/09/20/LeetCode-JAVA/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="小陈同学">
      <meta itemprop="description" content="求知若饥，虚心若愚">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="小陈同学">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          LeetCode-JAVA
        </h1>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-09-20 10:48:01" itemprop="dateCreated datePublished" datetime="2021-09-20T10:48:01+08:00">2021-09-20</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar-check"></i>
      </span>
      <span class="post-meta-item-text">更新于</span>
      <time title="修改时间：2022-01-01 22:33:01" itemprop="dateModified" datetime="2022-01-01T22:33:01+08:00">2022-01-01</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/" itemprop="url" rel="index"><span itemprop="name">学习笔记</span></a>
        </span>
    </span>

  
  
  <span class="post-meta-item">
    
    <span class="post-meta-item-icon">
      <i class="far fa-comment"></i>
    </span>
    <span class="post-meta-item-text">Valine：</span>
  
    <a title="valine" href="/2021/09/20/LeetCode-JAVA/#valine-comments" itemprop="discussionUrl">
      <span class="post-comments-count valine-comment-count" data-xid="/2021/09/20/LeetCode-JAVA/" itemprop="commentCount"></span>
    </a>
  </span>
  
  
    <span class="post-meta-break"></span>
    <span class="post-meta-item" title="本文字数">
      <span class="post-meta-item-icon">
        <i class="far fa-file-word"></i>
      </span>
      <span class="post-meta-item-text">本文字数：</span>
      <span>60k</span>
    </span>
    <span class="post-meta-item" title="阅读时长">
      <span class="post-meta-item-icon">
        <i class="far fa-clock"></i>
      </span>
      <span class="post-meta-item-text">阅读时长 &asymp;</span>
      <span>54 分钟</span>
    </span>
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
        <p>按照<a target="_blank" rel="noopener" href="https://github.com/changgyhub/leetcode_101">《Leetcode101-A Leetcode Gringding Guide》</a>顺序记录。除此之外，开始正视代码书写规范。</p>
<span id="more"></span> 
<h1 id="贪心算法"><a href="#贪心算法" class="headerlink" title="贪心算法"></a>贪心算法</h1><h2 id="445-分发饼干-easy"><a href="#445-分发饼干-easy" class="headerlink" title="445 分发饼干 easy"></a>445 分发饼干 easy</h2><p>依次满足胃口最小的孩子。可以想到先排序，然后再去分配。注意当满足了孩子后,cookie再加一，因为一个饼干只能用一次。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//知识点</span></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">length()：String类的一个方法</span></span><br><span class="line"><span class="comment">字符串.length()</span></span><br><span class="line"><span class="comment">length() 方法用于返回字符串的长度。</span></span><br><span class="line"><span class="comment">长度等于字符串中 16 位 Unicode 代码单元的数量。</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">length：类的属性</span></span><br><span class="line"><span class="comment">数组.length</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">findContentChildren</span><span class="params">(<span class="keyword">int</span>[] g, <span class="keyword">int</span>[] s)</span> </span>&#123;</span><br><span class="line">        Arrays.sort(g);</span><br><span class="line">        Arrays.sort(s);</span><br><span class="line">        <span class="keyword">int</span> cookie = <span class="number">0</span>, child = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span>(child &lt; g.length &amp;&amp; cookie &lt; s.length)&#123;</span><br><span class="line">            <span class="keyword">if</span>(g[child] &lt;= s[cookie])&#123;</span><br><span class="line">                child++;</span><br><span class="line">            &#125;</span><br><span class="line">            cookie++;<span class="comment">//饼干只能用一次，满足条件再加1。</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> child;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="135-分发糖果-hard"><a href="#135-分发糖果-hard" class="headerlink" title="135 分发糖果 hard"></a>135 分发糖果 hard</h2><p>首先建立一个数组，然后初始化为1，也就是每个人都先分到一颗糖。然后从左往右边遍历，如果右边的孩子得分高于左边，则右边的孩子糖果数=左边的孩子糖果数+1，注意这里不是直接加1.因为分数可能是依次增加，还要求分数高的糖果多。然后从右往左遍历，如果左边的孩子分数大于右边孩子分数并且左边孩子的糖果数不如右边孩子糖果数，则左边孩子糖果数=右边孩子糖果数+1，这种情况对应于左边分数大于右边。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;<span class="comment">//根据书上的思路写的，写法比较冗余。</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">candy</span><span class="params">(<span class="keyword">int</span>[] ratings)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> candys[] = <span class="keyword">new</span> <span class="keyword">int</span>[ratings.length];</span><br><span class="line">        <span class="keyword">int</span> count = <span class="number">0</span>; </span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; ratings.length; i++)&#123;</span><br><span class="line">            candys[i] = <span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; ratings.length-<span class="number">1</span>; i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(ratings[i+<span class="number">1</span>] &gt; ratings[i])&#123;</span><br><span class="line">                candys[i+<span class="number">1</span>] = candys[i] +<span class="number">1</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i = ratings.length-<span class="number">1</span>; i &gt; <span class="number">0</span> ; i--)&#123;</span><br><span class="line">            <span class="keyword">if</span>(ratings[i-<span class="number">1</span>] &gt; ratings[i] &amp;&amp; candys[i-<span class="number">1</span>] &lt;=  candys[i])&#123;</span><br><span class="line">                candys[i-<span class="number">1</span>] = candys[i] +<span class="number">1</span> ;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; ratings.length; i++)&#123;</span><br><span class="line">            count += candys[i]; </span><br><span class="line">        &#125;</span><br><span class="line">    <span class="keyword">return</span> count;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;<span class="comment">//这个有点不一样，分别创建两个数组，对应满足左右两个规则。然后分别取两个数组的最大值，为什么这样做可以？有个评论写得很清晰,如下。</span></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">为什么取最大值是正确的思考：</span></span><br><span class="line"><span class="comment">很多人说这个问题显而易见，不值得讨论，但我相信还是有人像我一样不理解，在这里说一下我的想法</span></span><br><span class="line"><span class="comment">我疑惑的问题不是取最大值为啥是最优解，而是取最大值后为啥不影响某一规则的成立。</span></span><br><span class="line"><span class="comment">我们取序列中的任意两点，A B</span></span><br><span class="line"><span class="comment">如果 A &gt; B ,则按照左规则处理后，B不会比A多；按照右规则处理后，A一定比B多，那么A一定会被更新（变大），但L、R规则仍然成立：B不会比A多，A一定比B多；</span></span><br><span class="line"><span class="comment">同理可讨论 A&lt;B;</span></span><br><span class="line"><span class="comment">当 A == B，A、B的值无论如何更新，都不影响 L、R规则</span></span><br><span class="line"><span class="comment">综上，取最大值后不影响某一规则的成立。</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">candy</span><span class="params">(<span class="keyword">int</span>[] ratings)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span>[] left = <span class="keyword">new</span> <span class="keyword">int</span>[ratings.length];</span><br><span class="line">        <span class="keyword">int</span>[] right = <span class="keyword">new</span> <span class="keyword">int</span>[ratings.length];</span><br><span class="line">        Arrays.fill(left, <span class="number">1</span>);</span><br><span class="line">        Arrays.fill(right, <span class="number">1</span>);<span class="comment">//把right数组全部填充为1，如果长度是长，则right=[1,1,1]</span></span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">1</span>; i &lt; ratings.length; i++)</span><br><span class="line">            <span class="keyword">if</span>(ratings[i] &gt; ratings[i - <span class="number">1</span>]) left[i] = left[i - <span class="number">1</span>] + <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">int</span> count = left[ratings.length - <span class="number">1</span>];</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i = ratings.length - <span class="number">2</span>; i &gt;= <span class="number">0</span>; i--) &#123;</span><br><span class="line">            <span class="keyword">if</span>(ratings[i] &gt; ratings[i + <span class="number">1</span>]) right[i] = right[i + <span class="number">1</span>] + <span class="number">1</span>;</span><br><span class="line">            count += Math.max(left[i], right[i]);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> count;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">作者：jyd</span><br><span class="line">链接：https:<span class="comment">//leetcode-cn.com/problems/candy/solution/candy-cong-zuo-zhi-you-cong-you-zhi-zuo-qu-zui-da-/</span></span><br><span class="line">来源：力扣（LeetCode）</span><br><span class="line">著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。</span><br></pre></td></tr></table></figure>
<h2 id="435-无重叠区间-medium-可动态规划"><a href="#435-无重叠区间-medium-可动态规划" class="headerlink" title="435 无重叠区间 medium(可动态规划)"></a>435 无重叠区间 medium(可动态规划)</h2><p>这里学到了Arrays.sort()新写法，开头一直纠结怎么把书上C++的排序用java表达(java用得少)。这里是要移除区间的最小个数，贪心的策略是：在选择要保留区间时，选择的区间结尾越小，余留给其他区间的空间就越大，就能保留更多的区间。首先对尾巴进行递增排序，也就是每个区间的第二个数字排序。然后对prve赋值为第一个区间的尾巴。开始进入for循环，如果第二个区间的头是小于prev，也就是在第一个的区间内，需要进行移除，如果大于了prev，则保留区间，然后prev赋值给第二个区间的尾巴，以此类推。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//首先是知识点笔记，部分来源于网络 Arrays.sort()</span></span><br><span class="line">System.out.println(Arrays.deepToString(intervals));<span class="comment">//这样可以输出二维数组的样子</span></span><br><span class="line">System.out.println(Arrays.toString(intervals));<span class="comment">//输出的貌似是地址，反正是这样的[[I@49993335, [I@20322d26, [I@192b07fd, [I@64bfbc86]</span></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">方法一、使用Comparable接口：</span></span><br><span class="line"><span class="comment">让待排序对象所在的类实现Comparable接口，并重写Comparable接口中的compareTo() 。方法缺点是只能按照一种规则排序</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">方法二、使用Comparator接口 （推荐使用）</span></span><br><span class="line"><span class="comment">如果一个类要实现java.util.Comparator接口：它一定要实现</span></span><br><span class="line"><span class="comment">int compare(T o1, T o2) 函数，而另一个可以不实现（boolean equals(Object obj)） 。</span></span><br><span class="line"><span class="comment">使用编写排序方式类实现Comparator接口，并重写新Comparator接口中的compare()方法。优点：想用什么方式排就用什么方式排。</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">原理：观察Arrays.sort()源码如下：</span></span><br><span class="line"><span class="comment">public static &lt;T&gt; void sort(T[] a, Comparator&lt;? super T&gt; c) &#123;</span></span><br><span class="line"><span class="comment">        if (c == null) &#123;</span></span><br><span class="line"><span class="comment">            sort(a);</span></span><br><span class="line"><span class="comment">        &#125; else &#123;</span></span><br><span class="line"><span class="comment">            if (LegacyMergeSort.userRequested)</span></span><br><span class="line"><span class="comment">                legacyMergeSort(a, c);</span></span><br><span class="line"><span class="comment">            else</span></span><br><span class="line"><span class="comment">                TimSort.sort(a, 0, a.length, c, null, 0, 0);</span></span><br><span class="line"><span class="comment">        &#125;</span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment">所以，在传入要排序数组时，还可以传入一个Compartor接口（比较器），然后这个接口中要重写一个compare()方法，这个重写的compare()方法就是我们自己规定的比较规则。</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">实现Comparator接口，必须实现下面这个函数：</span></span><br><span class="line"><span class="comment">@Override</span></span><br><span class="line"><span class="comment">public int compare(CommentVo o1, CommentVo o2) &#123;</span></span><br><span class="line"><span class="comment">           return o1.getTime().compareTo(o2.getTime());</span></span><br><span class="line"><span class="comment">&#125;</span></span><br><span class="line"><span class="comment">这里o1表示位于前面的对象，o2表示后面的对象</span></span><br><span class="line"><span class="comment">返回-1（或负数），表示不需要交换01和02的位置，o1排在o2前面，asc</span></span><br><span class="line"><span class="comment">返回1（或正数），表示需要交换01和02的位置，o1排在o2后面，desc</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="comment">//所以本题的sort，比较尾巴就是interval1[1]，为了递增，左边尾巴减右边尾巴，负数就不需要交换，正数就交换。</span></span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;<span class="comment">//这个是贪心策略写法</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">eraseOverlapIntervals</span><span class="params">(<span class="keyword">int</span>[][] intervals)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(intervals.length == <span class="number">0</span>)&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        Arrays.sort(intervals,<span class="keyword">new</span> Comparator&lt;<span class="keyword">int</span> []&gt;()&#123;</span><br><span class="line">            <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">compare</span><span class="params">(<span class="keyword">int</span>[] interval1, <span class="keyword">int</span>[] interval2)</span></span>&#123;</span><br><span class="line">                <span class="keyword">return</span> interval1[<span class="number">1</span>]-interval2[<span class="number">1</span>];</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);<span class="comment">//学废了吗？</span></span><br><span class="line">        <span class="keyword">int</span> total = <span class="number">0</span>, prev = intervals[<span class="number">0</span>][<span class="number">1</span>];</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">1</span>; i &lt; intervals.length; i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(intervals[i][<span class="number">0</span>] &lt; prev)&#123;</span><br><span class="line">                total++;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span>&#123;</span><br><span class="line">                prev = intervals[i][<span class="number">1</span>];</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">       </span><br><span class="line">    <span class="keyword">return</span> total;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h2 id="605-种花问题-easy"><a href="#605-种花问题-easy" class="headerlink" title="605 种花问题 easy"></a>605 种花问题 easy</h2><p>虽说是easy题，但是发现自己想的bug很多，看到了一个很清晰的解题方法：跳格法。注意题目是不能打破原来的种植规则！。情况1：当index遇到1的时候，也就是至少隔一格才能种花，所以i要跳两格。情况2：当index遇到0时候，如果下一格为0，则可以种花（此时n-1），并且顺便跳两格，这里还有个情况就是如果已经是最后一格了，那就也能种花，一开始会想，万一最后一格的前面一格是1呢？注意这个情况不会发生，因为你是跳格法，你跳的index就代表是可能种花的，只需要考虑后面就行。如果下一个格子为1(比如0100)，则这格不能种花，则i要跳3格才可以种花。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;<span class="comment">//这个写得比较清晰，但是冗余。</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">canPlaceFlowers</span><span class="params">(<span class="keyword">int</span>[] flowerbed, <span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">         <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; flowerbed.length &amp;&amp; n &gt;<span class="number">0</span>;)&#123;</span><br><span class="line">             <span class="keyword">if</span>(flowerbed[i] == <span class="number">1</span>)&#123;</span><br><span class="line">                 i += <span class="number">2</span>;</span><br><span class="line">             &#125;</span><br><span class="line">             <span class="keyword">else</span> <span class="keyword">if</span>((flowerbed[i] ==<span class="number">0</span> &amp;&amp; i == flowerbed.length-<span class="number">1</span>) || (flowerbed[i] ==<span class="number">0</span> &amp;&amp; flowerbed[i+<span class="number">1</span>] == <span class="number">0</span>))&#123;</span><br><span class="line">                 n--;</span><br><span class="line">                 i += <span class="number">2</span>;     </span><br><span class="line">             &#125;</span><br><span class="line">             <span class="keyword">else</span> <span class="keyword">if</span>(flowerbed[i] ==<span class="number">0</span> &amp;&amp; flowerbed[i+<span class="number">1</span>] == <span class="number">1</span>)&#123;</span><br><span class="line">                 i +=<span class="number">3</span>;</span><br><span class="line">             &#125;</span><br><span class="line">         &#125;</span><br><span class="line">        <span class="keyword">return</span> n &lt;= <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;<span class="comment">//这个省略了点。</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">canPlaceFlowers</span><span class="params">(<span class="keyword">int</span>[] flowerbed, <span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">         <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; flowerbed.length &amp;&amp; n &gt;<span class="number">0</span>;)&#123;</span><br><span class="line">             <span class="keyword">if</span>(flowerbed[i] == <span class="number">1</span>)&#123;</span><br><span class="line">                 i += <span class="number">2</span>;</span><br><span class="line">             &#125;</span><br><span class="line">             <span class="keyword">else</span> <span class="keyword">if</span>(i == flowerbed.length-<span class="number">1</span> ||  flowerbed[i+<span class="number">1</span>] == <span class="number">0</span>)&#123;<span class="comment">//因为你的flowerbed[i]不是1就是0，上一步已经判断好了是不是1，所以如果不是1的话自然跳到这里。</span></span><br><span class="line">                 n--;</span><br><span class="line">                 i += <span class="number">2</span>;     </span><br><span class="line">             &#125;</span><br><span class="line">             <span class="keyword">else</span> &#123;</span><br><span class="line">                 i += <span class="number">3</span>;</span><br><span class="line">             &#125;</span><br><span class="line">         &#125;</span><br><span class="line">        <span class="keyword">return</span> n &lt;= <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="452-用最少数量的箭引爆气球-medium-和435相似"><a href="#452-用最少数量的箭引爆气球-medium-和435相似" class="headerlink" title="452 用最少数量的箭引爆气球 medium(和435相似)"></a>452 用最少数量的箭引爆气球 medium(和435相似)</h2><p>这个题我的思路是，首先还是对尾巴进行升序排列，然后赋值prev给第一个数的尾巴，开始进行for循环比较第二个数，如果prev大于第二个数的头，也就是这个箭还是可以穿过去，不需要考虑尾巴，因为题目说了头一定比尾巴小。然后如果prev比头小，就说明穿不过去了，这时候就箭的数目加1.以此类推，这个注意count初始值为1，因为本身至少都需要一支箭，可以试试只有一个区间，在循环内counnt是不增加的。这里和435比较：435是不重叠区间，而这里刚好是重叠区间。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;<span class="comment">//看了一遍435后自己写的，注意这里的升序有点和435的不一样，因为会有一个用例存在溢出问题，如果按照435的写。[[-2147483646,-2147483645],[2147483646,2147483647]]，sort后是[[2147483646,2147483647],[-2147483646,-2147483645]]，因为他们相减后会溢出，所以用到小于来比较。</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">findMinArrowShots</span><span class="params">(<span class="keyword">int</span>[][] points)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(points.length == <span class="number">0</span>)&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        Arrays.sort(points,<span class="keyword">new</span> Comparator&lt;<span class="keyword">int</span> []&gt;()&#123;</span><br><span class="line">            <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">compare</span><span class="params">(<span class="keyword">int</span>[] points1, <span class="keyword">int</span>[] points2)</span></span>&#123;</span><br><span class="line">                <span class="keyword">if</span>(points1[<span class="number">1</span>] &lt; points2[<span class="number">1</span>])&#123;</span><br><span class="line">                    <span class="keyword">return</span> -<span class="number">1</span>;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">else</span> <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br><span class="line">       </span><br><span class="line">        <span class="keyword">int</span> count = <span class="number">1</span>,prev = points[<span class="number">0</span>][<span class="number">1</span>];</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">1</span>; i &lt; points.length; i++)&#123;</span><br><span class="line">           <span class="keyword">if</span>(points[i][<span class="number">0</span>] &gt; prev)&#123;</span><br><span class="line">                count++;</span><br><span class="line">                prev = points[i][<span class="number">1</span>];</span><br><span class="line">            &#125;           </span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> count;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*这个for循环就比较详细，但是没必要，增加运行的时间。</span></span><br><span class="line"><span class="comment">    for(int i = 1; i &lt; points.length; i++)&#123;</span></span><br><span class="line"><span class="comment">            if(points[i][0] &lt; prev)&#123;</span></span><br><span class="line"><span class="comment">                continue;</span></span><br><span class="line"><span class="comment">            &#125;</span></span><br><span class="line"><span class="comment">            else if(points[i][0] &gt; prev)&#123;</span></span><br><span class="line"><span class="comment">                count++;</span></span><br><span class="line"><span class="comment">                System.out.println(count);</span></span><br><span class="line"><span class="comment">                prev = points[i][1];</span></span><br><span class="line"><span class="comment">            &#125;           </span></span><br><span class="line"><span class="comment">        &#125;</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>
<h2 id="763-划分字母区间-medium"><a href="#763-划分字母区间-medium" class="headerlink" title="763 划分字母区间 medium"></a>763 划分字母区间 medium</h2><p>自己想的思路比较复杂，太冗余，而且可能考虑的东西不够全面。官方思路:首先用一个长度为26的数组a把每个字母的最后一个位置进行标记。设置start和end，开始循环字符串，访问每个字母，通过之前a来获取他的最后一个位置endc，令end=max（end，endc）。如果循环到i等于end，就说明之前的字母都包括在这个区间内，那就让长度写入partitio，并令start=end+1。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//知识点总结，</span></span><br><span class="line">List&lt;Integer&gt; partition = <span class="keyword">new</span> ArrayList&lt;Integer&gt;();</span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">List是一个接口</span></span><br><span class="line"><span class="comment">&lt;&gt;表示了List里面放的对象是什么类型的，上面List里面放的必须是Integer类型的</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">ArrayList类是一个特殊的数组–动态数组。通过添加和删除元素，就可以动态改变数组的长度。</span></span><br><span class="line"><span class="comment">优点：</span></span><br><span class="line"><span class="comment">1、支持自动改变大小 2、可以灵活的插入元素 3、可以灵活的删除元素</span></span><br><span class="line"><span class="comment">局限：</span></span><br><span class="line"><span class="comment">比一般的数组的速度慢一些；</span></span><br><span class="line"><span class="comment">可以调用 List接口里面的内置函数,add,get等方法</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line">last[s.charAt(i) - <span class="string">&#x27;a&#x27;</span>] = i;</span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">String s = &quot;www.runoob.com&quot;;</span></span><br><span class="line"><span class="comment">char result = s.charAt(6);</span></span><br><span class="line"><span class="comment">输出为n</span></span><br><span class="line"><span class="comment">所以本题这样的做法，可以把每个字母的最后一个位置记录下来</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">partitionLabels</span><span class="params">(String s)</span> </span>&#123;</span><br><span class="line">          <span class="keyword">int</span> start = <span class="number">0</span>, end = <span class="number">0</span>;</span><br><span class="line">          <span class="keyword">int</span>[] last =<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">26</span>];</span><br><span class="line">          List&lt;Integer&gt; partition = <span class="keyword">new</span> ArrayList&lt;Integer&gt;();</span><br><span class="line">          <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; s.length(); i++)&#123;</span><br><span class="line">              last[s.charAt(i) - <span class="string">&#x27;a&#x27;</span>] = i;</span><br><span class="line">          &#125;</span><br><span class="line">          <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; s.length(); i++)&#123;</span><br><span class="line">              end = Math.max(end, last[s.charAt(i) - <span class="string">&#x27;a&#x27;</span>]);</span><br><span class="line">              <span class="keyword">if</span>(i == end)&#123;</span><br><span class="line">                  partition.add(end - start + <span class="number">1</span>);</span><br><span class="line">                  start = end + <span class="number">1</span>;</span><br><span class="line">              &#125;</span><br><span class="line">          &#125;</span><br><span class="line">          <span class="keyword">return</span> partition;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="122-买卖股票的最佳时机2-easy-可动态规划"><a href="#122-买卖股票的最佳时机2-easy-可动态规划" class="headerlink" title="122 买卖股票的最佳时机2 easy(可动态规划)"></a>122 买卖股票的最佳时机2 easy(可动态规划)</h2><p>还是没有独立想出来，想得太复杂，一直纠结怎么用区间来解答。官方解答太多数学公式，总体来说就是只要选择贡献大于0的区间，然后一直累加利润，但是这个做法是不知道第几次买卖的，只能求利润，对于负数，则和0比较就行。秒呀！</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">maxProfit</span><span class="params">(<span class="keyword">int</span>[] prices)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> price = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">1</span>; i &lt; prices.length; i++)&#123;</span><br><span class="line">            price += Math.max(<span class="number">0</span>, prices[i] - prices[i-<span class="number">1</span>]);</span><br><span class="line">        &#125;</span><br><span class="line">    <span class="keyword">return</span> price;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="406-根据身高重建队列-medium"><a href="#406-根据身高重建队列-medium" class="headerlink" title="406 根据身高重建队列 medium"></a>406 根据身高重建队列 medium</h2><p><a target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/queue-reconstruction-by-height/solution/xian-pai-xu-zai-cha-dui-dong-hua-yan-shi-suan-fa-g/">网友思路</a>：首先遇到这种数对问题，先排序。根据第一个元素正向排序，根据第二个元素反向排序，或者根据第一个元素反向排序，根据第二个元素正向排序，往往能够简化解题过程。在本题目中，先对数对进行排序，按照数对的元素 1 降序排序，按照数对的元素 2 升序排序。原因是，按照元素 1 进行降序排序，对于每个元素，在其之前的元素的个数，就是大于等于他的元素的数量，而按照第二个元素正向排序，我们希望 k 大的尽量在后面，减少插入操作的次数。小陈补充：如果第一个位置降序，第二个位置也降序排，再按照这样写法去插入的话，有部分用例是不能通过的，比如a[[7,0],[6,1],[5,2]]下一个待插入的数是[5,0]，按照算法应该插入到第一个位置，变成a[[5,0],[7,0],[6,1],[5,2]]这时候我们就发现[5,2]已经错误了，因为前面有三个数大于或者等于了。也就是你插入后，你得保证后面没有等于你的数插入，所以，第二个位置的排序，要升序！！！保证同胞小弟位置(第二个位置)先安排好。我们可以这样缕清楚，a里面已经插入的数都是比后面待插入的数大或者相等，如果后面待插入的数第二个位置比a的长度小，那么就是说他来选位置插，反之，他就插到最后面。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//知识点</span></span><br><span class="line"><span class="comment">//这个题可以学到compare对两个位置进行排序的写法，具体看下面的答案这里不多说</span></span><br><span class="line"> List&lt;<span class="keyword">int</span>[]&gt; list = <span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">这个的话是双向链表，比创建数组a更加方便，创建数组的话，当你的情况是a的长度大小大于people[i][1]时，你是要插入到a的people[i][1]的位置，这时候你需要进行移动a[people[i][1]]以及后面的每个数据1位，然后才能插进去，这样麻烦。</span></span><br><span class="line"><span class="comment">最后转成list.toArray(new int[list.size()][]);返回即可。</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">可以对比763的</span></span><br><span class="line"><span class="comment">List&lt;Integer&gt; partition = new ArrayList&lt;Integer&gt;();</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">int</span>[][] reconstructQueue(<span class="keyword">int</span>[][] people) &#123;</span><br><span class="line">        Arrays.sort(people, <span class="keyword">new</span> Comparator&lt;<span class="keyword">int</span> []&gt;()&#123;</span><br><span class="line">            <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">compare</span><span class="params">(<span class="keyword">int</span>[] people1, <span class="keyword">int</span>[] people2)</span></span>&#123;</span><br><span class="line">                <span class="keyword">if</span>(people1[<span class="number">0</span>] != people2[<span class="number">0</span>])&#123;</span><br><span class="line">                    <span class="keyword">return</span> people2[<span class="number">0</span>] - people1[<span class="number">0</span>];</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">else</span>&#123;</span><br><span class="line">                    <span class="keyword">return</span> people1[<span class="number">1</span>] - people2[<span class="number">1</span>];</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br><span class="line">        List&lt;<span class="keyword">int</span>[]&gt; list = <span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; people.length; i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(list.size() &gt; people[i][<span class="number">1</span>])&#123;</span><br><span class="line">                list.add(people[i][<span class="number">1</span>],people[i]);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span>&#123;</span><br><span class="line">                list.add(list.size(),people[i]);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> list.toArray(<span class="keyword">new</span> <span class="keyword">int</span>[list.size()][]);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="665-非递减数列-easy"><a href="#665-非递减数列-easy" class="headerlink" title="665 非递减数列 easy"></a>665 非递减数列 easy</h2><p>第一次看题看错了，看成只移动一个数。这个题是改变一个数！虽然是easy，但是并不一定easy。<a target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/non-decreasing-array/solution/yi-ding-yao-rang-ni-nong-dong-wei-shi-ya-u9te/">网友解答很清晰</a>：本题是要维持一个非递减的数列，所以遇到递减的情况时（nums[i] &gt; nums[i + 1]），要么将前面的元素缩小，要么将后面的元素放大。但是本题唯一的易错点就在这，如果将nums[i]缩小，可能会导致其无法融入前面已经遍历过的非递减子数列；如果将nums[i + 1]放大，可能会导致其后续的继续出现递减；所以要采取贪心的策略，在遍历时，每次需要看连续的三个元素，也就是瞻前顾后，遵循以下两个原则：需要尽可能不放大nums[i + 1]，这样会让后续非递减更困难；如果缩小nums[i]，但不破坏前面的子序列的非递减性；算法步骤:遍历数组，如果遇到递减：还能修改：修改方案1：将nums[i]缩小至nums[i + 1]；修改方案2：将nums[i + 1]放大至nums[i]；不能修改了：直接返回false；</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;<span class="comment">//只能修改一次，让数组递增。</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">checkPossibility</span><span class="params">(<span class="keyword">int</span>[] nums)</span> </span>&#123;</span><br><span class="line">      <span class="keyword">if</span>(nums.length == <span class="number">1</span>)&#123;</span><br><span class="line">          <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">boolean</span> flag = nums[<span class="number">0</span>] &lt;= nums[<span class="number">1</span>] ? <span class="keyword">true</span> : <span class="keyword">false</span>;<span class="comment">//一开始第一个数小于第二个数，则拥有一次修改的机会。</span></span><br><span class="line">      <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">1</span>; i &lt; nums.length-<span class="number">1</span> ; i++)&#123;</span><br><span class="line">          <span class="keyword">if</span>(nums[i] &gt; nums[i+<span class="number">1</span>])&#123;<span class="comment">//开始出现递减情况。i大于后面一个数了</span></span><br><span class="line">              <span class="keyword">if</span>(flag)&#123;<span class="comment">//如果拥有修改机会</span></span><br><span class="line">                  <span class="keyword">if</span>(nums[i+<span class="number">1</span>] &gt;= nums[i-<span class="number">1</span>])&#123;<span class="comment">//如果i的后面一个数比i的前面一个数大的话，就说明他们是递增，让i缩小的话，也没有破坏非递减性，并且不影响i+1后面的序列。</span></span><br><span class="line">                      nums[i] = nums[i+<span class="number">1</span>];<span class="comment">//这时候就让i缩小</span></span><br><span class="line">                  &#125;</span><br><span class="line">                  <span class="keyword">else</span>&#123;</span><br><span class="line">                      nums[i+<span class="number">1</span>] = nums[i];<span class="comment">//这个情况就是i后面的一个数比i前面的一个数小，但是同时i后面的数还小于i，所以只能让i后面的数扩大为i。</span></span><br><span class="line">                  &#125;</span><br><span class="line">                  flag = <span class="keyword">false</span>;<span class="comment">//用掉了唯一的一次修改机会了</span></span><br><span class="line">               &#125;</span><br><span class="line">               <span class="keyword">else</span> &#123;</span><br><span class="line">                 <span class="keyword">return</span> <span class="keyword">false</span>;<span class="comment">//再出现递减情况，但是已经没有修改机会了，直接返回false。</span></span><br><span class="line">               &#125;</span><br><span class="line">           &#125;</span><br><span class="line">       &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;<span class="comment">//若nums(0) &gt; nums(1)的话，flag是false，且后面没有出现递减，所以已经是可以用修改一次来递增，也就是把第一个数变成第二个数就满足，所以直接返回true。</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h1 id="双指针"><a href="#双指针" class="headerlink" title="双指针"></a>双指针</h1><h2 id="167-两数之和2-easy"><a href="#167-两数之和2-easy" class="headerlink" title="167 两数之和2 easy"></a>167 两数之和2 easy</h2><p>注意题目给的数组是非递减顺序排列（也就是总体递增，然后可能有两个相邻的数是相等），所以思路上很简单，两个变量去追踪这个数组，一头一尾巴，如果两数之和小于target，左边就需要移动一位，反之则右边需要移动一位。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;<span class="comment">//一开始根据书上思路写的，超时了~~~可能是暴力解法的原因，而且这个代码尚未验证是否正确。</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">int</span>[] twoSum(<span class="keyword">int</span>[] numbers, <span class="keyword">int</span> target) &#123;</span><br><span class="line">        <span class="keyword">int</span> j = numbers.length-<span class="number">1</span>;</span><br><span class="line">        <span class="keyword">int</span>[] ans = <span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">2</span>];</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; numbers.length-<span class="number">1</span> &amp;&amp; i &lt; j;)&#123;</span><br><span class="line">           <span class="keyword">if</span>(numbers[i] + numbers[j] == target)</span><br><span class="line">           &#123;</span><br><span class="line">               ans[<span class="number">0</span>] = i+<span class="number">1</span>;</span><br><span class="line">               ans[<span class="number">1</span>] = j+<span class="number">1</span>;</span><br><span class="line">              </span><br><span class="line">           &#125;</span><br><span class="line">           <span class="keyword">else</span> <span class="keyword">if</span>(numbers[i] + numbers[j] &lt; target)&#123;</span><br><span class="line">               i++;</span><br><span class="line">           &#125;</span><br><span class="line">           <span class="keyword">else</span> <span class="keyword">if</span>(numbers[i] + numbers[j] &gt; target)&#123;</span><br><span class="line">               j--;</span><br><span class="line">           &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> ans;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">int</span>[] twoSum(<span class="keyword">int</span>[] numbers, <span class="keyword">int</span> target) &#123;</span><br><span class="line">        <span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int</span> j = numbers.length-<span class="number">1</span>;</span><br><span class="line">        <span class="comment">//int[] ans = new int[2];</span></span><br><span class="line">        <span class="keyword">while</span>(i &lt; j)&#123;</span><br><span class="line">            <span class="keyword">int</span>  sum = numbers[i] + numbers[j];</span><br><span class="line">            <span class="keyword">if</span>(sum == target)&#123;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">if</span>(sum &lt; target)&#123;</span><br><span class="line">                i++;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">if</span>(sum &gt; target)&#123;</span><br><span class="line">                j--;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="keyword">int</span>[]&#123;i + <span class="number">1</span>, j + <span class="number">1</span>&#125;;<span class="comment">//这样就不用先去定义一个数组了。</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="88-合并两个有序数组-easy"><a href="#88-合并两个有序数组-easy" class="headerlink" title="88 合并两个有序数组 easy"></a>88 合并两个有序数组 easy</h2><p>题目给的是两个非递减数组，思路是用m,n来指向两个数组的尾巴，还有pos来定位。首先要注意是在数组1的基础上去排，不需要额外开辟一个数组。pos定位在数组1的尾巴，开始对比两个数组的尾巴，哪个大就先复制过去。这里最后要注意，如果数组1复制完了，但是数组2还有，务必要记得继续复制。反之如果数组2复制完了，则不需要操作，因为数组1本身就是非递减，而且返回的数组就是他自己。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">merge</span><span class="params">(<span class="keyword">int</span>[] nums1, <span class="keyword">int</span> m, <span class="keyword">int</span>[] nums2, <span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">         <span class="keyword">int</span> pos = m-- + n-- -<span class="number">1</span>;<span class="comment">//这样写的话就少了一步，别忘了数组大小和数组位置是相差1.</span></span><br><span class="line">         <span class="keyword">while</span>(m &gt;= <span class="number">0</span> &amp;&amp; n &gt;= <span class="number">0</span>)&#123;</span><br><span class="line">             nums1[pos--] = nums1[m] &gt; nums2[n] ? nums1[m--] :nums2[n--];<span class="comment">//注意是哪个大才会自减减哦。不是每次都自减减。</span></span><br><span class="line">         &#125;</span><br><span class="line">         <span class="keyword">while</span>(n &gt;= <span class="number">0</span>)&#123;</span><br><span class="line">             nums1[pos--] = nums2[n--];<span class="comment">//务必不要忘记如果数组2还没复制完这个事！！！！！此时的数组1已经复制完啦！！！</span></span><br><span class="line">         &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="142-环形链表2-medium"><a href="#142-环形链表2-medium" class="headerlink" title="142 环形链表2 medium"></a>142 环形链表2 medium</h2><p>这个题涉及了一些数学计算，感谢<a target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/linked-list-cycle-ii/solution/linked-list-cycle-ii-kuai-man-zhi-zhen-shuang-zhi-/">网友</a>讲解，这里复述一下：设置两个指针，一个为fast，一个为slow，fast每次走2步，slow每次走1步，设链表为a+b个节点，a为抵达环状的步数，b为环状的节点数。没有环状的链表很容易考虑，这里直接讲有环状的情况，也就是fast和slow会相遇：首先可以得到第一个关系式f=2s，这个是slow和fast的步数关系。第二个关系式是f=s+nb，因为fast比slow快，所以最终一定能追上，这时候呢，其实fast比slow多走了n个环。根据这两个关系，可以得到<mark>f=2nb</mark>,<mark>s=nb</mark>。接下来我们考虑，一个指针从头走到环状开头走过的步数<mark>k=a+nb</mark>，当n为0，也就是你走了a步到了环状的门口，然后n=1的话，你相当于绕了一圈环，然后又到了门口。现在有了三个表达式，从head结点走到入环点需要走:a + nb， 而slow已经走了nb（之前推了相遇的时候他们两个的关系），那么slow再走a步就是入环点了,如何知道slow刚好走了a步？fast从新从head开始和slow指针一起走，再相遇时刚好就是a步。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * class ListNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     ListNode next;</span></span><br><span class="line"><span class="comment"> *     ListNode(int x) &#123;</span></span><br><span class="line"><span class="comment"> *         val = x;</span></span><br><span class="line"><span class="comment"> *         next = null;</span></span><br><span class="line"><span class="comment"> *     &#125;</span></span><br><span class="line"><span class="comment"> * &#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> ListNode <span class="title">detectCycle</span><span class="params">(ListNode head)</span> </span>&#123;</span><br><span class="line">        ListNode fast = head, slow = head;</span><br><span class="line">        <span class="keyword">while</span>(<span class="keyword">true</span>)&#123;</span><br><span class="line">            <span class="keyword">if</span>(fast == <span class="keyword">null</span> || fast.next == <span class="keyword">null</span>)&#123;<span class="comment">//注意别忘了是两个条件</span></span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            fast = fast.next.next;</span><br><span class="line">            slow = slow.next;</span><br><span class="line">            <span class="keyword">if</span>(fast == slow)&#123;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        fast = head;</span><br><span class="line">        <span class="keyword">while</span>(slow != fast)&#123;</span><br><span class="line">            fast = fast.next;</span><br><span class="line">            slow = slow.next;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> fast;</span><br><span class="line">        </span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="76-最小覆盖子串-hard"><a href="#76-最小覆盖子串-hard" class="headerlink" title="76 最小覆盖子串 hard"></a>76 最小覆盖子串 hard</h2><p>依旧是<a target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/minimum-window-substring/solution/tong-su-qie-xiang-xi-de-miao-shu-hua-dong-chuang-k/993501">网友</a>的思路，这个题在于需要考虑不少东西，这里简单描述一下：首先是建立一个128的ASCII列表，第一步先记录t中每个字符的数量。定义好l和r初始位置，还有用count去记录还需要的字符数量，这样就不用每次去查看need中哪个字符还大于0。开始while循环，用r去遍历整个S串，经过每个r的位置去提取字符c，首先判断c在need中的情况，如果是大于0，说明这个字符是符合t串的。然后减去一个count，代表已经找到了一个符合的字符，接下来是need中减去字符c的数量，注意，这里也包括不在t中的字符，不在t的中字符减去自然是为负数，代表这个字符是多余的。然后判断count为0的情况，count为0，代表已经找到符合的子串了，但是题目要求的size是最小的，所以可以缩减范围，当l小于r，并且里面有多余的字符，我们首先在need中加回去，然后移动l，然后开始重置size的大小，注意这时候的start变成新的l。接来下是移动l，看看还有没有更小的窗口，注意这里用start去保存这个开始的位置，而不是直接用l，这是有含义的，因为你的r是要遍历整个S串，这样你才知道哪个窗口是最小的，所以只有当size更小时候，我们才去更新更新start值，再加上size大小，就可以找到最小的串位置。这时候你无需当心l和r移动的位置了。务必务必注意，移动l的时候，请记得更新need和count以及l！！！</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">minWindow</span><span class="params">(String s, String t)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span>[] need = <span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">128</span>];</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span> ; i &lt; t.length() ; i++)&#123;</span><br><span class="line">        need[t.charAt(i)]++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> l = <span class="number">0</span>, r = <span class="number">0</span>, start = <span class="number">0</span>, size = Integer.MAX_VALUE, count = t.length();</span><br><span class="line">    <span class="keyword">while</span> (r &lt; s.length())&#123;</span><br><span class="line">        <span class="keyword">char</span> c = s.charAt(r);</span><br><span class="line">        <span class="keyword">if</span> (need[c] &gt; <span class="number">0</span>)&#123;</span><br><span class="line">            count--;</span><br><span class="line">        &#125;</span><br><span class="line">        need[c]--;</span><br><span class="line">        <span class="keyword">if</span>(count == <span class="number">0</span>)&#123;</span><br><span class="line">           <span class="keyword">while</span>(l &lt; r &amp;&amp; need[s.charAt(l)] &lt; <span class="number">0</span>)&#123;</span><br><span class="line">               need[s.charAt(l)]++;</span><br><span class="line">               l++;</span><br><span class="line">           &#125;</span><br><span class="line">           <span class="keyword">if</span> (r -l + <span class="number">1</span> &lt; size)&#123;</span><br><span class="line">               size = r - l + <span class="number">1</span>;</span><br><span class="line">               start = l;</span><br><span class="line">           &#125; </span><br><span class="line">           need[s.charAt(l)]++;</span><br><span class="line">           count++;</span><br><span class="line">           l++;</span><br><span class="line">       &#125;</span><br><span class="line">       r++;</span><br><span class="line">       </span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> size == Integer.MAX_VALUE ? <span class="string">&quot;&quot;</span> : s.substring(start, start + size);</span><br><span class="line">&#125;&#125;</span><br></pre></td></tr></table></figure>
<h2 id="633-平方数之和-medium"><a href="#633-平方数之和-medium" class="headerlink" title="633 平方数之和 medium"></a>633 平方数之和 medium</h2><p>和167的很像，这里<a target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/sum-of-square-numbers/solution/shuang-zhi-zhen-de-ben-zhi-er-wei-ju-zhe-ebn3/">网友</a>非常详细说明为什么i++和j–不会错过答案。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">judgeSquareSum</span><span class="params">(<span class="keyword">int</span> c)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">long</span> i = <span class="number">0</span>,j =(<span class="keyword">long</span>) Math.sqrt(c);<span class="comment">//如果直接写成c，会超时。理论上也是应该对的。</span></span><br><span class="line">    <span class="keyword">while</span>(i &lt;= j)&#123;</span><br><span class="line">       <span class="keyword">long</span> sum = i*i + j*j;</span><br><span class="line">       <span class="keyword">if</span>( sum == c )&#123;</span><br><span class="line">           <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">       &#125;</span><br><span class="line">       <span class="keyword">else</span> <span class="keyword">if</span>( sum &lt; c )&#123;</span><br><span class="line">           i++;</span><br><span class="line">       &#125;</span><br><span class="line">       <span class="keyword">else</span> &#123;</span><br><span class="line">           j--;</span><br><span class="line">       &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h2 id="680-验证回文字符串2-easy"><a href="#680-验证回文字符串2-easy" class="headerlink" title="680 验证回文字符串2 easy"></a>680 验证回文字符串2 easy</h2><p>这个题虽然是简单题，但是还是看了<a target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/valid-palindrome-ii/solution/cong-liang-ce-xiang-zhong-jian-zhao-dao-bu-deng-de/403606">网友</a>思路：用双指针去对比，一个在头l，一个在尾巴r，当遇到不相等的情况，我们可以让l加1个位置，或者让r减去一个位置，因为题目说了可以最多删除一个字符，然后再用一个函数去对比子字符串。这里我一开始想到的是用一个计数器去判断删除的次数，后来发现其实不需要，比如abxbgga，要删除两次才行，你只要仔细看代码，发现只要一次之后不行就直接false了，所以不用考虑加一个计数器的问题，那么删除一个字符是体现在r-1或者l+1上</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">validPalindrome</span><span class="params">(String s)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> l = <span class="number">0</span>, r = s.length()-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">while</span>(l &lt; r)&#123;</span><br><span class="line">        <span class="keyword">if</span>(s.charAt(l) != s.charAt(r))&#123;</span><br><span class="line">            <span class="keyword">return</span> judegesub(s, l+<span class="number">1</span>, r) || judegesub(s, l, r-<span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        l++;</span><br><span class="line">        r--;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">judegesub</span><span class="params">(String s, <span class="keyword">int</span> l, <span class="keyword">int</span> r)</span></span>&#123;</span><br><span class="line">        <span class="keyword">while</span>(l &lt; r)&#123;</span><br><span class="line">            <span class="keyword">if</span>(s.charAt(l) != s.charAt(r))&#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        l++;</span><br><span class="line">        r--;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h2 id="524-通过删除字母匹配到字典里最长单词-medium"><a href="#524-通过删除字母匹配到字典里最长单词-medium" class="headerlink" title="524 通过删除字母匹配到字典里最长单词 medium"></a>524 通过删除字母匹配到字典里最长单词 medium</h2><p>这个题我一开始考虑的是，首先跟上一个题的区别是，这个题的意思是可以删除好几个元素，然后第二个不同的是，这个题有多个词，是不是要用暴力算法一个个去看？看了官方解答后，发现被上一题绕进去了。大概重复下解法：用双指针思路，i和j分别指向t(字典中的词)和s的第一个字母，注意这里是每个字典的词都会遍历，然后如果匹配，则i和j同时移动一位，如果不匹配，i不动，j+1。直到最后i要是等于这个词的长度的话，就代表全部匹配到。注意这里是长度，长度和单词最后一个字符位置是相差1的。题目中说要长度最长和序号最低的。所以自然有一个长度对比以及序号对比，序号对比是用compareTo函数，这个是对比ASCII对比，也就是序号在前的话是小于0。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//知识点</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">findLongestWord</span><span class="params">(String s, List&lt;String&gt; dictionary)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span> (String t : dictionary) &#123;</span><br><span class="line">          System.out.print(t);</span><br><span class="line">          System.out.print(<span class="string">&quot; &quot;</span>);</span><br><span class="line">        &#125;  </span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//输入是[&quot;ale&quot;,&quot;apple&quot;,&quot;monkey&quot;,&quot;plea&quot;]这里会依次输出ale apple monkey plea </span></span><br><span class="line"></span><br><span class="line">关于compareTo:</span><br><span class="line">返回值是整型，它是先比较对应字符的大小(ASCII码顺序)如果第一个字符和参数的第一个字符不等，结束比较，返回他们之间的长度差值，如果第一个字符和参数的第一个字符相等，则以第二个字符和参数的第二个字符做比较，以此类推,直至比较的字符或被比较的字符有一方结束。</span><br><span class="line"></span><br><span class="line">如果参数字符串等于此字符串，则返回值 <span class="number">0</span>；</span><br><span class="line">如果此字符串小于字符串参数，则返回一个小于 <span class="number">0</span> 的值；</span><br><span class="line">如果此字符串大于字符串参数，则返回一个大于 <span class="number">0</span> 的值。</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">findLongestWord</span><span class="params">(String s, List&lt;String&gt; dictionary)</span> </span>&#123;</span><br><span class="line">        String res = <span class="string">&quot;&quot;</span>;</span><br><span class="line">        <span class="keyword">for</span> (String t : dictionary) &#123;</span><br><span class="line">            <span class="keyword">int</span> i = <span class="number">0</span>, j = <span class="number">0</span>;</span><br><span class="line">            <span class="keyword">while</span> (i &lt; t.length() &amp;&amp; j &lt; s.length()) &#123;</span><br><span class="line">                <span class="keyword">if</span> (t.charAt(i) == s.charAt(j)) &#123;</span><br><span class="line">                    ++i;</span><br><span class="line">                &#125;</span><br><span class="line">                ++j;<span class="comment">//注意这里，如果匹配的话，j是在这里++，而不是在上面的if语句，因为这里还有一个就是如果不匹配的话，j也要++，而这时候i不变，所以这个写法可以同时满足两个条件</span></span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (i == t.length()) &#123;</span><br><span class="line">                <span class="keyword">if</span> (t.length() &gt; res.length() || (t.length() == res.length() &amp;&amp; t.compareTo(res) &lt; <span class="number">0</span>)) &#123;</span><br><span class="line">                    res = t;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h1 id="二分查找"><a href="#二分查找" class="headerlink" title="二分查找"></a>二分查找</h1><h2 id="69-Sqrt-x-easy"><a href="#69-Sqrt-x-easy" class="headerlink" title="69 Sqrt(x) easy"></a>69 Sqrt(x) easy</h2><p>这个题是看了官方解法，其实思路就是二分法，每次寻找中间值，如果中间值的平方小于输入值，则把左边的边界设置为mid+1，反之如果大于输入值，则把右边界设置为mid-1，这里注意一个问题就是mid * mid前面要加long，不然超过范围。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">mySqrt</span><span class="params">(<span class="keyword">int</span> x)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> l = <span class="number">0</span>, r = x, ans = -<span class="number">1</span>;</span><br><span class="line">        <span class="keyword">while</span> (l &lt;= r) &#123;</span><br><span class="line">            <span class="keyword">int</span> mid = l + (r - l) / <span class="number">2</span>;</span><br><span class="line">            <span class="keyword">if</span> ((<span class="keyword">long</span>) mid * mid &lt;= x)&#123;</span><br><span class="line">                ans = mid;</span><br><span class="line">                l = mid + <span class="number">1</span>;</span><br><span class="line">            &#125;<span class="keyword">else</span> &#123;</span><br><span class="line">                r = mid - <span class="number">1</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    <span class="keyword">return</span> ans;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="34-在排序数组中查找元素的第一个和最后一个位置-medium"><a href="#34-在排序数组中查找元素的第一个和最后一个位置-medium" class="headerlink" title="34 在排序数组中查找元素的第一个和最后一个位置 medium"></a>34 在排序数组中查找元素的第一个和最后一个位置 medium</h2><p>这里有一个网友的<a target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/solution/tu-jie-er-fen-zui-qing-xi-yi-dong-de-jia-ddvc/">二分法模板</a>，关于这个题，分了两步，首先是寻找第一个target，循环内部条件是num[mid]大于等于target，然后用模板1，寻找最后出现的target，用模板2。至于为什么分开模板1和2，有个网友解释很清楚：因为取左边第一个target时，当nums[mid]==target时，中间位置的右边元素一定不是target出现的第一个位置，所以下次搜索区间是[left,mid],right=mid;取最后一个target时，当nums[mid]==target时，中间位置的左边元素一定不是target出现的最后一个位置，所以下次搜索区间是[mid，right],left=mid。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//模板1</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">bsearch_1</span><span class="params">(<span class="keyword">int</span> l, <span class="keyword">int</span> r)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">while</span> (l &lt; r)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">int</span> mid = (l + r)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span> (check(mid)) r = mid;</span><br><span class="line">        <span class="keyword">else</span> l = mid + <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> l;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//模板2</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">bsearch_2</span><span class="params">(<span class="keyword">int</span> l, <span class="keyword">int</span> r)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">while</span> (l &lt; r)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">int</span> mid = ( l + r + <span class="number">1</span> ) /<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span> (check(mid)) l = mid;</span><br><span class="line">        <span class="keyword">else</span> r = mid - <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> l;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">总结归纳：当l=mid时，mid=(l+r+1)/2，当l=mid+1，mid=(l+r)/2，至于为什么请看网友解释，这个题要多次理解。</span></span><br><span class="line"><span class="comment">这里复制了网友的解释：什么时候用模板1，什么时候用模板2？</span></span><br><span class="line"><span class="comment">假设初始时我们的二分区间为[l,r]，每次二分缩小区间时，如果左边界l要更新为 l = mid，此时我们就要使用模板2，让 mid = (l + r + 1)/ 2，否则while会陷入死循环。如果左边界l更新为l = mid + 1,此时我们就使用模板1，让mid = (l + r)/2。因此，模板1和模板2本质上是根据代码来区分的，而不是应用场景。如果写完之后发现是l = mid，那么在计算mid时需要加上1，否则如果写完之后发现是l = mid + 1，那么在计算mid时不能加1。</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">int</span>[] searchRange(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> target) &#123;</span><br><span class="line">        <span class="keyword">if</span> (nums.length == <span class="number">0</span>) <span class="keyword">return</span> <span class="keyword">new</span> <span class="keyword">int</span>[]&#123;-<span class="number">1</span>, -<span class="number">1</span>&#125;;<span class="comment">//上来就要记住这个。</span></span><br><span class="line">        <span class="keyword">int</span> l = <span class="number">0</span>, r = nums.length - <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">while</span> (l &lt; r)&#123;</span><br><span class="line">            <span class="keyword">int</span> mid = (l + r) / <span class="number">2</span>;</span><br><span class="line">            <span class="keyword">if</span> (nums[mid] &gt;= target) r = mid ;<span class="comment">//比目标值大，则寻找左区间，右边变为mid，左边不动。</span></span><br><span class="line">            <span class="keyword">else</span> l = mid + <span class="number">1</span>;<span class="comment">//比目标值小，寻找右区间，左边变成mid+1，右边不动。</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (nums[r] != target) <span class="keyword">return</span> <span class="keyword">new</span> <span class="keyword">int</span>[]&#123;-<span class="number">1</span>,-<span class="number">1</span>&#125;;<span class="comment">//这个特别容易忘记的。</span></span><br><span class="line">        <span class="keyword">int</span> L = r;</span><br><span class="line">        l = <span class="number">0</span>; r = nums.length - <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">while</span> (l &lt; r)&#123;</span><br><span class="line">            <span class="keyword">int</span> mid = (l + r + <span class="number">1</span>) / <span class="number">2</span>;</span><br><span class="line">            <span class="keyword">if</span> (nums[mid] &lt;= target) l = mid ;<span class="comment">//比目标值小，寻找右区间，左边变成mid，右边不变。</span></span><br><span class="line">            <span class="keyword">else</span> r = mid - <span class="number">1</span>;<span class="comment">//比目标值大，寻找左区间，右边变成mid-1，左边不变。</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="keyword">int</span>[]&#123;L,r&#125;;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="81-搜索旋转排序数组-II-medium"><a href="#81-搜索旋转排序数组-II-medium" class="headerlink" title="81 搜索旋转排序数组 II medium"></a>81 搜索旋转排序数组 II medium</h2><p>找数组的目标数，这个题就是说本来的数组是增序的，但是现在相当于在中间断开，然后再连起来，就变成一个旋转数组。所以，旋转数组的特性的有一部分是增序的。先依旧找到中点位置，后面解释看代码。这个<a target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/solution/zai-javazhong-ji-bai-liao-100de-yong-hu-by-reedfan/">coder</a>把一些情况得很清楚。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">解题思路：</span></span><br><span class="line"><span class="comment">本题是需要使用二分查找，怎么分是关键，举个例子：</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">第一类</span></span><br><span class="line"><span class="comment">1011110111 和 1110111101 这种。此种情况下 nums[start] == nums[mid]，分不清到底是前面有序还是后面有序，此时 start++ 即可。相当于去掉一个重复的干扰项。</span></span><br><span class="line"><span class="comment">第二类</span></span><br><span class="line"><span class="comment">22 33 44 55 66 77 11 这种，也就是 nums[start] &lt; nums[mid]。此例子中就是 2 &lt; 5；</span></span><br><span class="line"><span class="comment">这种情况下，前半部分有序。因此如果 nums[start] &lt;=target&lt;nums[mid]，则在前半部分找，否则去后半部分找。</span></span><br><span class="line"><span class="comment">第三类</span></span><br><span class="line"><span class="comment">66 77 11 22 33 44 55 这种，也就是 nums[start] &gt; nums[mid]。此例子中就是 6 &gt; 2；</span></span><br><span class="line"><span class="comment">这种情况下，后半部分有序。因此如果 nums[mid] &lt;target&lt;=nums[end]。则在后半部分找，否则去前半部分找</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">search</span><span class="params">(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> target)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> start = <span class="number">0</span>, end = nums.length - <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">while</span> (start &lt;= end) &#123;</span><br><span class="line">            <span class="keyword">int</span> mid = (start + end) / <span class="number">2</span>;</span><br><span class="line">            <span class="keyword">if</span> (nums[mid] == target)&#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (nums[start] == nums[mid])&#123;<span class="comment">//因为数组会存在重复数字，如果中点和左端相等，我们不能确定在左区间全部相等，还是右边区间全部相等，这种情况，可以把start右移动一个，当然这种操作我们不能说是完全的二分法，这个题只是部分地方用到二分法。</span></span><br><span class="line">                start++;<span class="comment">//无法判断哪个区间是增序的</span></span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> (nums[mid] &lt;= nums[end]) &#123;<span class="comment">//右区间是增序的</span></span><br><span class="line">                <span class="keyword">if</span> (target &gt; nums[mid] &amp;&amp; target &lt;= nums[end]) &#123;<span class="comment">//然后在右区间内判断target，用二分法。target在mid和end中间，这里需要注意，target是要小于等于end。我觉得要这么去想，你想如果都等于mid，那肯定是直接返回true，所以有mid比较这边是开区间</span></span><br><span class="line">                    start = mid + <span class="number">1</span>;<span class="comment">//就让start移动到mid右边</span></span><br><span class="line">                &#125;<span class="keyword">else</span> &#123;</span><br><span class="line">                    end = mid -<span class="number">1</span>;<span class="comment">//反之，让end移动到mid左边</span></span><br><span class="line">                &#125;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;<span class="comment">//这个情况则是左区间增序</span></span><br><span class="line">                <span class="keyword">if</span> (target &lt; nums[mid] &amp;&amp; target &gt;= nums[start]) &#123;<span class="comment">//这里需要注意，target是要大于等于start</span></span><br><span class="line">                    end = mid - <span class="number">1</span>;</span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    start = mid + <span class="number">1</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="154-寻找旋转排序数组中的最小值-II-hard"><a href="#154-寻找旋转排序数组中的最小值-II-hard" class="headerlink" title="154 寻找旋转排序数组中的最小值 II hard"></a>154 寻找旋转排序数组中的最小值 II hard</h2><p>这个题也是旋转数组，和上个题的区别是，1.上个题是找target，这个题是找最小值。2.这个题旋转多次。<a target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array-ii/solution/154-find-minimum-in-rotated-sorted-array-ii-by-jyd/">这个作者解释得不错</a>，把作者思路拷贝到了下面了，注意一下这个题，旋转后每个数字的序号保持原来不变，也就是原来是0位置，旋转后序号还是0。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">    -思路-</span></span><br><span class="line"><span class="comment">    旋转数组肯定将nums分为两个有序的数组，分为别nums1和nums2。并且假设nums1中的元素均大于等于nums2中的元素</span></span><br><span class="line"><span class="comment">    那么我们要求的元素就是nums2的首元素</span></span><br><span class="line"><span class="comment">    --步骤--</span></span><br><span class="line"><span class="comment">    如果nums[mid] &gt; nums[right],说明此时的mid严格的在nums1当中。（这时候最小值在[mid,right]上？所以把区间缩到这来，我理解的），那么nums2的首元素设为i的话，就应当是：mid &lt; i &lt;= right。</span></span><br><span class="line"><span class="comment">    取left = mid + 1;附其他解释：当 nums[mid] &gt; nums[right]时，mid一定在第 1 个排序数组中，i 一定满足 mid &lt; i &lt;= right，因此执行 left = mid + 1；</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    如果nums[mid] &lt; nums[right],说明此时的mid严格的在nums2当中。（这时候最小值在[left,mid]上？所以把区间缩到这来，我理解的）也就是：mid &lt;= i &lt; right</span></span><br><span class="line"><span class="comment">    取right = mid(注意这里没有mid-1)；附其他作者解释：当 nums[mid] &lt; nums[right] 时，mid 一定在第 2 个排序数组中，i一定满足 left &lt; i &lt;= mid，因此执行 right = mid；</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    如果nums[mid] == nums[right],细分为三种情况。</span></span><br><span class="line"><span class="comment">        情况一：[1,1,1,1,1,1,1,1]</span></span><br><span class="line"><span class="comment">        情况二：[4,5,6,7,1,1,1,1,1,1]</span></span><br><span class="line"><span class="comment">        情况二：[4,5,6,7,0,1,1,1,1,1]</span></span><br><span class="line"><span class="comment">    取right--便可，这个很关键！！！！</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    另外一个作者解释了为什么这样：</span></span><br><span class="line"><span class="comment">    我们采用 right = right - 1 解决此问题，证明：</span></span><br><span class="line"><span class="comment">    此操作不会使数组越界：因为迭代条件保证了 right &gt; left &gt;= 0；</span></span><br><span class="line"><span class="comment">    此操作不会使最小值丢失：假设 nums[right]是最小值，有两种情况：</span></span><br><span class="line"><span class="comment">    若 nums[right]是唯一最小值：那就不可能满足判断条件 nums[mid] == nums[right]，因为 mid &lt; right（left != right 且 mid = (left + right) // 2 向下取整）；</span></span><br><span class="line"><span class="comment">    若 nums[right]不是唯一最小值，由于 mid &lt; right 而 nums[mid] == nums[right]，即还有最小值存在于 [left, right - 1][left,right−1] 区间，因此不会丢失最小值。</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">作者：jyd</span></span><br><span class="line"><span class="comment">链接：https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array-ii/solution/154-find-minimum-in-rotated-sorted-array-ii-by-jyd/</span></span><br><span class="line"><span class="comment">来源：力扣（LeetCode）</span></span><br><span class="line"><span class="comment">著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">findMin</span><span class="params">(<span class="keyword">int</span>[] nums)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> left = <span class="number">0</span>, right = nums.length - <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">while</span> (left &lt; right) &#123;</span><br><span class="line">            <span class="keyword">int</span> mid = (left + right) / <span class="number">2</span>;</span><br><span class="line">            <span class="keyword">if</span> (nums[mid] == nums[right]) &#123;</span><br><span class="line">                right--;</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> (nums[mid] &lt; nums[right]) &#123;</span><br><span class="line">                right = mid;</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> (nums[mid] &gt; nums[right]) &#123;</span><br><span class="line">                left = mid + <span class="number">1</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    <span class="keyword">return</span> nums[right]; <span class="comment">//貌似nums[left]也是可以的。其实看了下，最后left=mid+1也就是等于right，所以这样也就是两种写法都是一样。</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="540-有序数组中的单一元素-meidum"><a href="#540-有序数组中的单一元素-meidum" class="headerlink" title="540. 有序数组中的单一元素 meidum"></a>540. 有序数组中的单一元素 meidum</h2><p>这个题是找到唯一的单身狗，注意题目是升序的，不过貌似与升序没关系。这里先整理下官方的清晰解答：因为这个模块是讲二分法，所以不讲解暴力算法。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">首先要知道，这个数组一定是奇数个，因为只有一个单身狗！</span></span><br><span class="line"><span class="comment">用 halvesAreEven = (right - mid) % 2 == 0来判断哪一侧元素为奇数，因为单身狗肯定在这一侧。</span></span><br><span class="line"><span class="comment">情况1：mid 和 mid+1是同元素。然后mid元素把两侧都分为偶数个，当我们把mid+1拿掉后，右侧就变成奇数个了，也就是右侧肯定存在单身狗，设置left = mid + 2</span></span><br><span class="line"><span class="comment">情况2；mid 和 mid+1是同元素。然后mid元素把两侧都分为奇数个，当我们把mid+1拿掉后，右侧是偶数个，所以左侧存在单身狗，设置right = mid - 1 </span></span><br><span class="line"><span class="comment">情况3：mid 和 mid-1是同元素。然后mid元素把两侧都分为偶数个，当我们把mid-1拿掉后，左侧就是奇数个了，所以左侧存在单身狗，设置right = mid - 2</span></span><br><span class="line"><span class="comment">情况4：mid 和 mid-1是同元素。然后mid元素把两侧都分为奇数个，当我们把mid-1拿掉后，右侧就存在单身狗，所以left = mid + 1</span></span><br><span class="line"><span class="comment">首先判断mid和左边还是右边的元素相等，然后通过halvesAreEven判断左右两侧是奇还是偶。</span></span><br><span class="line"><span class="comment">这里只举例情况1和2，因为这是放在一起的。现在已经知道了mid和mid+1相等，然后再想，如果mid把两侧分为了偶数个(单纯讲个数，与数组位置无关)，也就是mid的位置是一个偶数(数组从0计算)，然后整个数组肯定是奇数个，也就是最后一个数的位置也是偶数，所以当halvesAreEven为true，就说明符合情况1，反之符合情况2。</span></span><br><span class="line"><span class="comment">注意写代码的时候别忘了mid就是单身狗的情况。</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">下面这个方法也是二分，但是仅对偶数索引进行二分搜索，比上面的方法简洁，而且不用单独考虑mid是单身狗的情况，因为else就是包含了mid是单身狗或者左侧存在单身狗。</span></span><br><span class="line"><span class="comment">然后就是简洁点，整理下上面的思路，我们确保mid是偶数的位置，如果是奇数就减去1，然后检查 mid 的元素是否与其后面的索引相同。如果相同，则我们知道 mid 不是单个元素。</span></span><br><span class="line"><span class="comment">且单个元素在 mid 之后。则我们将 left 设置为 mid + 2。</span></span><br><span class="line"><span class="comment">如果不是，则我们知道单个元素位于 mid，或者在 mid 之前。我们将 right 设置为 mid。</span></span><br><span class="line"><span class="comment">一旦 left == right，则当前搜索空间为 1 个元素，那么该元素为单个元素，我们将返回它。</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">知识点：int mid = left + (right - left) / 2;</span></span><br><span class="line"><span class="comment">为什么前面还要加left?因为防止超出整型数据溢出。可以看看前面的题有没有这种情况！！</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">singleNonDuplicate</span><span class="params">(<span class="keyword">int</span>[] nums)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> left = <span class="number">0</span>, right = nums.length - <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">while</span> (left &lt; right) &#123;</span><br><span class="line">            <span class="keyword">int</span> mid = left + (right - left) / <span class="number">2</span>;</span><br><span class="line">            <span class="keyword">if</span> (mid % <span class="number">2</span> == <span class="number">1</span> ) mid--;</span><br><span class="line">            <span class="keyword">if</span> (nums[mid] == nums[mid+<span class="number">1</span>]) &#123;</span><br><span class="line">                left = mid + <span class="number">2</span>;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                right = mid;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    <span class="keyword">return</span> nums[right];<span class="comment">//left也可以，第一次写的时候写成了mid，先不说结果对不对，这里语法就存在问题，因为mid在while里面，所以系统会检测不到mid，是一个局部变量。</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="4-寻找两个正序数组的中位数-hard"><a href="#4-寻找两个正序数组的中位数-hard" class="headerlink" title="4 寻找两个正序数组的中位数 hard"></a>4 寻找两个正序数组的中位数 hard</h2><p>这个题虽然看上去是可以合并起来去找，但是，由于有时间复杂度的要求，所以用二分法比较好，坦白说，确实hard。详细解释<a target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/median-of-two-sorted-arrays/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-w-2/">点击这里看解法三</a>。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//用的代码是官方的，但是上面说的解释更清楚。</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">double</span> <span class="title">findMedianSortedArrays</span><span class="params">(<span class="keyword">int</span>[] nums1, <span class="keyword">int</span>[] nums2)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> length1 = nums1.length, length2 = nums2.length;</span><br><span class="line">        <span class="keyword">int</span> totallength = length1 + length2;</span><br><span class="line">        <span class="keyword">if</span> (totallength % <span class="number">2</span> == <span class="number">1</span>)&#123;<span class="comment">//两个数组长度和为奇数情况</span></span><br><span class="line">           <span class="keyword">int</span> midIndex = totallength / <span class="number">2</span>;<span class="comment">//注意totallength是个数，而不是数组中的序号(从0开始)。</span></span><br><span class="line">           <span class="keyword">double</span> median = getKthElement(nums1, nums2, midIndex + <span class="number">1</span>);</span><br><span class="line">           <span class="keyword">return</span> median;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;<span class="comment">//两个数组长度合为偶数情况</span></span><br><span class="line">            <span class="keyword">int</span> midIndex1 = totallength / <span class="number">2</span> -<span class="number">1</span>, midIndex2 =totallength / <span class="number">2</span>;</span><br><span class="line">            <span class="keyword">double</span> median = (getKthElement(nums1, nums2, midIndex1 + <span class="number">1</span>) + getKthElement(nums1, nums2, midIndex2 + <span class="number">1</span>)) / <span class="number">2.0</span>;</span><br><span class="line">            <span class="keyword">return</span> median;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getKthElement</span><span class="params">(<span class="keyword">int</span>[] nums1, <span class="keyword">int</span>[] nums2, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">        <span class="comment">//下面是官方写的</span></span><br><span class="line">        <span class="comment">/* 主要思路：要找到第 k (k&gt;1) 小的元素，那么就取 pivot1 = nums1[k/2-1] 和 pivot2 = nums2[k/2-1] 进行比较</span></span><br><span class="line"><span class="comment">         * 这里的 &quot;/&quot; 表示整除</span></span><br><span class="line"><span class="comment">         * nums1 中小于等于 pivot1 的元素有 nums1[0 .. k/2-2] 共计 k/2-1 个</span></span><br><span class="line"><span class="comment">         * nums2 中小于等于 pivot2 的元素有 nums2[0 .. k/2-2] 共计 k/2-1 个</span></span><br><span class="line"><span class="comment">         * 取 pivot = min(pivot1, pivot2)，两个数组中小于等于 pivot 的元素共计不会超过 (k/2-1) + (k/2-1) &lt;= k-2 个</span></span><br><span class="line"><span class="comment">         * 这样 pivot 本身最大也只能是第 k-1 小的元素</span></span><br><span class="line"><span class="comment">         * 如果 pivot = pivot1，那么 nums1[0 .. k/2-1] 都不可能是第 k 小的元素。把这些元素全部 &quot;删除&quot;，剩下的作为新的 nums1 数组</span></span><br><span class="line"><span class="comment">         * 如果 pivot = pivot2，那么 nums2[0 .. k/2-1] 都不可能是第 k 小的元素。把这些元素全部 &quot;删除&quot;，剩下的作为新的 nums2 数组</span></span><br><span class="line"><span class="comment">         * 由于我们 &quot;删除&quot; 了一些元素（这些元素都比第 k 小的元素要小），因此需要修改 k 的值，减去删除的数的个数</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line"></span><br><span class="line">        <span class="keyword">int</span> length1 = nums1.length, length2 = nums2.length;</span><br><span class="line">        <span class="keyword">int</span> index1 = <span class="number">0</span>, index2 = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int</span> kthElement = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">while</span> (<span class="keyword">true</span>) &#123;<span class="comment">//边界情况</span></span><br><span class="line">            <span class="keyword">if</span> (index1 == length1) &#123;</span><br><span class="line">                <span class="keyword">return</span> nums2[index2 + k - <span class="number">1</span>];</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (index2 == length2) &#123;</span><br><span class="line">                <span class="keyword">return</span> nums1[index1 + k - <span class="number">1</span>];</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (k == <span class="number">1</span>) &#123;<span class="comment">//当k剩下一个的时候，也就是比较剩下哪个数谁比较小。</span></span><br><span class="line">                <span class="keyword">return</span> Math.min(nums1[index1], nums2[index2]);</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="comment">//正常情况 </span></span><br><span class="line">            <span class="keyword">int</span> half = k / <span class="number">2</span>;</span><br><span class="line">            <span class="keyword">int</span> newIndex1 = Math.min(index1 + half, length1) - <span class="number">1</span>;<span class="comment">// k/2-1</span></span><br><span class="line">            <span class="keyword">int</span> newIndex2 = Math.min(index2 + half, length2) - <span class="number">1</span>;<span class="comment">// k/2-1</span></span><br><span class="line">            <span class="keyword">int</span> pivot1 = nums1[newIndex1] ,pivot2 = nums2[newIndex2];</span><br><span class="line">            <span class="keyword">if</span> (pivot1 &lt;= pivot2) &#123;</span><br><span class="line">                k = k -(newIndex1 - index1 + <span class="number">1</span>);</span><br><span class="line">                index1 = newIndex1 + <span class="number">1</span>;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                k = k -(newIndex2 - index2 + <span class="number">1</span>);<span class="comment">//加1是因为要去掉pivot这个元素</span></span><br><span class="line">                index2 = newIndex2 + <span class="number">1</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;<span class="comment">//这个是while语句的结束</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//由于这个题实在是费脑，这里详细举例子，按照代码思路一步步来</span></span><br><span class="line">nums1:<span class="number">1</span> <span class="number">3</span> <span class="number">4</span> <span class="number">9</span></span><br><span class="line">nums2:<span class="number">1</span> <span class="number">2</span> <span class="number">3</span> <span class="number">4</span> <span class="number">5</span> <span class="number">6</span> <span class="number">7</span> <span class="number">8</span> <span class="number">9</span></span><br><span class="line">开始计算： </span><br><span class="line">length1=<span class="number">4</span>,length2=<span class="number">9</span></span><br><span class="line">totallength=<span class="number">13</span></span><br><span class="line">判断为奇数，midIndex=<span class="number">6</span> 传入到子函数(nums1，nums2,<span class="number">6</span>+<span class="number">1</span>)<span class="comment">//也就是第7个数是中位数</span></span><br><span class="line"></span><br><span class="line">下面是子函数循环情况</span><br><span class="line"></span><br><span class="line">下面说的 排 是指两个数组合并起来，从小到大排第几个的意思</span><br><span class="line">length1=<span class="number">4</span>,length2=<span class="number">9</span></span><br><span class="line">正常情况</span><br><span class="line">第一轮<span class="keyword">while</span></span><br><span class="line">half=<span class="number">7</span>/<span class="number">2</span>=<span class="number">3</span></span><br><span class="line">newIndex1=<span class="number">3</span>-<span class="number">1</span>=<span class="number">2</span>,newIndex2=<span class="number">3</span>-<span class="number">1</span>=<span class="number">2</span><span class="comment">//比较nums1[k/2-1],nums2[k/2-1]的元素，本题也就是nums1[2],nums2[2]</span></span><br><span class="line"></span><br><span class="line">[pivot]元素</span><br><span class="line"><span class="number">1</span> <span class="number">3</span> [<span class="number">4</span>] <span class="number">9</span></span><br><span class="line"><span class="number">1</span> <span class="number">2</span> [<span class="number">3</span>] <span class="number">4</span> <span class="number">5</span> <span class="number">6</span> <span class="number">7</span> <span class="number">8</span> <span class="number">9</span>    可以看出nums2[<span class="number">2</span>]的更小，把nums2[<span class="number">2</span>]及其前面元素全部去掉，然后更新index2和k</span><br><span class="line"></span><br><span class="line">这里需要理解为什么更新k和index2，我们要找的数是排序第七个(不是从<span class="number">0</span>计算)的数，然后分别比较两个数组的nums[k/<span class="number">2</span>-<span class="number">1</span>]</span><br><span class="line">nums1 中小于等于 pivot1 的元素有 nums1[<span class="number">0</span> .. k/<span class="number">2</span>-<span class="number">2</span>] 共计 k/<span class="number">2</span>-<span class="number">1</span> 个，本题也就是<span class="number">2</span>个</span><br><span class="line">nums2 中小于等于 pivot2 的元素有 nums1[<span class="number">0</span> .. k/<span class="number">2</span>-<span class="number">2</span>] 共计 k/<span class="number">2</span>-<span class="number">1</span> 个，本题也就是<span class="number">2</span>个</span><br><span class="line">然后取两个数组中比较小的pivot，本题是num2[<span class="number">2</span>],可以推导，两个数组中小于等于 pivot 的元素共计不会超过 (k/<span class="number">2</span>-<span class="number">1</span>) + (k/<span class="number">2</span>-<span class="number">1</span>) &lt;= k-<span class="number">2</span> 个，也就是全部元素合并后小于等于nums2[<span class="number">2</span>]元素的不超过<span class="number">5</span>个，如果按照等式左边是为<span class="number">4</span>个，因为是整除，如果按照等式右边就直接是<span class="number">5</span>个。</span><br><span class="line">这样的话，即便取pivot本身最大也只能是第 k-<span class="number">1</span> 小的元素，也就是<span class="number">6</span>，但是按照上一行的分析，pivot元素是排第<span class="number">5</span>或者第<span class="number">6</span>，本题的话实际是排第<span class="number">5</span>。</span><br><span class="line">总之还不是第七个我们要找的元素。那么可以完全排除nums[<span class="number">2</span>]和左边的元素，这时候就要更新k和index2</span><br><span class="line">k更新：因为本身要找第<span class="number">7</span>个元素，现在已经排除了<span class="number">3</span>个元素了，所以k=<span class="number">7</span>-<span class="number">3</span>=<span class="number">4</span>，也就是在剩下的数组中找排第四个的元素，具体写法是<span class="number">7</span>-（<span class="number">2</span>-<span class="number">0</span>+<span class="number">1</span>)=<span class="number">4</span></span><br><span class="line">index2更新： index2=<span class="number">2</span>+<span class="number">1</span>=<span class="number">3</span>，也就是从nums2[<span class="number">3</span>]开始</span><br><span class="line">index1依旧为<span class="number">0</span></span><br><span class="line"></span><br><span class="line">第二轮<span class="keyword">while</span>   </span><br><span class="line">half=<span class="number">4</span>/<span class="number">2</span>=<span class="number">2</span></span><br><span class="line">newIndex1=<span class="number">0</span>+<span class="number">2</span>-<span class="number">1</span>=<span class="number">1</span>,newIndex2=<span class="number">3</span>+<span class="number">2</span>-<span class="number">1</span>=<span class="number">4</span></span><br><span class="line">下面标记|，代表左边的元素也就消除。</span><br><span class="line"><span class="number">1</span> [<span class="number">3</span>] <span class="number">4</span> <span class="number">9</span></span><br><span class="line"><span class="number">1</span> <span class="number">2</span> <span class="number">3</span> | <span class="number">4</span> [<span class="number">5</span>] <span class="number">6</span> <span class="number">7</span> <span class="number">8</span> <span class="number">9</span></span><br><span class="line">经过比较后，nums1[<span class="number">1</span>]及其左边消除</span><br><span class="line">k更新：因为本身要找第<span class="number">4</span>个元素，现在已经排除了<span class="number">2</span>个元素了，所以k=<span class="number">4</span>-<span class="number">2</span>=<span class="number">2</span>，也就是在剩下的数组中找排第二个的元素，具体写法是<span class="number">4</span>-（<span class="number">1</span>-<span class="number">0</span>+<span class="number">1</span>)=<span class="number">2</span></span><br><span class="line">index1更新： index1=<span class="number">1</span>+<span class="number">1</span>=<span class="number">2</span>，也就是从nums1[<span class="number">2</span>]开始</span><br><span class="line">index2依旧为<span class="number">3</span></span><br><span class="line"></span><br><span class="line">第三轮<span class="keyword">while</span></span><br><span class="line">half=<span class="number">2</span>/<span class="number">2</span>=<span class="number">1</span></span><br><span class="line">newIndex1=<span class="number">2</span>+<span class="number">1</span>-<span class="number">1</span>=<span class="number">2</span>,newIndex2=<span class="number">3</span>+<span class="number">1</span>-<span class="number">1</span>=<span class="number">3</span></span><br><span class="line"><span class="number">1</span> <span class="number">3</span> | [<span class="number">4</span>] <span class="number">9</span></span><br><span class="line"><span class="number">1</span> <span class="number">2</span> <span class="number">3</span> | [<span class="number">4</span>] <span class="number">5</span> <span class="number">6</span> <span class="number">7</span> <span class="number">8</span> <span class="number">9</span></span><br><span class="line">这里pivot元素相等，我们就假设上面的<span class="number">4</span>大于下面的<span class="number">4</span>，由于两个数相等，所以我们无论去掉哪个数组中的都行，因为去掉 <span class="number">1</span> 个总会保留 <span class="number">1</span> 个的，所以没有影响。</span><br><span class="line">经过比较后，nums2[<span class="number">3</span>]及其左边消除。</span><br><span class="line">k更新：因为本身要找第<span class="number">2</span>个元素，现在已经排除了<span class="number">1</span>个元素了，所以k=<span class="number">2</span>-<span class="number">1</span>=<span class="number">1</span>，也就是在剩下的数组中找排第二个的元素，具体写法是<span class="number">2</span>-（<span class="number">0</span>-<span class="number">0</span>+<span class="number">1</span>)=<span class="number">1</span></span><br><span class="line">index2更新： index2=<span class="number">3</span>+<span class="number">1</span>=<span class="number">4</span>，也就是从nums2[<span class="number">4</span>]开始</span><br><span class="line">index1依旧为<span class="number">2</span></span><br><span class="line"></span><br><span class="line">第四轮<span class="keyword">while</span></span><br><span class="line">k已经等于<span class="number">1</span>了，直接找剩下比较小的数就行。</span><br><span class="line"><span class="number">1</span> <span class="number">3</span> | [<span class="number">4</span>] <span class="number">9</span></span><br><span class="line"><span class="number">1</span> <span class="number">2</span> <span class="number">3</span> <span class="number">4</span> | [<span class="number">5</span>] <span class="number">6</span> <span class="number">7</span> <span class="number">8</span> <span class="number">9</span></span><br><span class="line">答案就是<span class="number">4</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">当然还有注意边界的情况，本题没有涉及。</span><br><span class="line">所谓边界的问题,也就是有可能其中一个数组过小，然后进行更新的时候会发现越界，这时候也就是这个小的数组数组全部已经小于第K个数据，然后我们之后关注大的数组找到k就行。</span><br></pre></td></tr></table></figure>
<h1 id="常用排序算法"><a href="#常用排序算法" class="headerlink" title="常用排序算法"></a>常用排序算法</h1><p><img src="/images/leetcode-java/4.jpg" alt="排序算法"></p>
<h2 id="快速排序"><a href="#快速排序" class="headerlink" title="快速排序"></a>快速排序</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//本代码是可执行代码，后面的排序算法可以直接用在本模板调用。</span></span><br><span class="line"><span class="comment">//快速排序就是每次把第一个数选为枢轴元素，然后左右扫描，右边扫描比它小的交换，左边扫描比它大的交换，最后放到正确的位置，最终左边的元素都比它小，右边的元素都比它大，然后左右递归。</span></span><br><span class="line"><span class="keyword">import</span> java.util.Arrays;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">sort</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> arr[] = &#123;<span class="number">6</span>,<span class="number">7</span>,<span class="number">8</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">9</span>,<span class="number">10</span>,<span class="number">0</span>,<span class="number">4</span>,<span class="number">6</span>,<span class="number">8</span>,<span class="number">7</span>,<span class="number">99</span>,<span class="number">77</span>,<span class="number">44</span>&#125;;<span class="comment">//初始化数组时用new与不用new是没区别的</span></span><br><span class="line">        <span class="keyword">int</span> temp[] = <span class="keyword">new</span> <span class="keyword">int</span>[arr.length];</span><br><span class="line">        <span class="keyword">int</span> size = arr.length;</span><br><span class="line">        quick_sort(arr, <span class="number">0</span>, size);<span class="comment">//实现快速排序</span></span><br><span class="line">        <span class="comment">//insertion_sort(arr,size);//实现插入排序</span></span><br><span class="line">        <span class="comment">//merge_sort(arr, 0, size, temp);//实现归并排序</span></span><br><span class="line">        <span class="comment">//bubble_sort(arr, 0, size);//实现冒泡排序</span></span><br><span class="line">        <span class="comment">//select_sort(arr,size);实现选择排序</span></span><br><span class="line">        System.out.println(Arrays.toString(arr));<span class="comment">//输出结果</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">quick_sort</span><span class="params">(<span class="keyword">int</span>[] arr,<span class="keyword">int</span> left, <span class="keyword">int</span> right)</span> </span>&#123;<span class="comment">//左闭右闭区间，也就是right一开始输入的是size</span></span><br><span class="line">        <span class="keyword">if</span> (left + <span class="number">1</span> &gt;= right) &#123;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">int</span> first = left, last = right - <span class="number">1</span>, key = arr[first];</span><br><span class="line">        <span class="keyword">while</span> (first &lt;last) &#123;</span><br><span class="line">            <span class="keyword">while</span> (first &lt; last &amp;&amp; arr[last] &gt;= key) &#123;<span class="comment">//右边扫描</span></span><br><span class="line">                --last;</span><br><span class="line">            &#125;</span><br><span class="line">            arr[first] = arr[last];</span><br><span class="line">            <span class="keyword">while</span> (first &lt; last &amp;&amp; arr[first] &lt;= key) &#123;<span class="comment">//左边扫描</span></span><br><span class="line">                ++first;</span><br><span class="line">            &#125;</span><br><span class="line">            arr[last] = arr[first];</span><br><span class="line">        &#125;</span><br><span class="line">        arr[first] = key;<span class="comment">//把枢轴元素放到正确的位置</span></span><br><span class="line">        quick_sort(arr, left, first);<span class="comment">//左边递归</span></span><br><span class="line">        quick_sort(arr, first + <span class="number">1</span>, right);<span class="comment">//右边递归</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h2 id="插入排序"><a href="#插入排序" class="headerlink" title="插入排序"></a>插入排序</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//从第二个数开始，只要比前面小就一直交换。这样每轮的前i个数都是从小到大排好序，就好像插队一样，一直插。</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">insertion_sort</span><span class="params">(<span class="keyword">int</span>[] arr, <span class="keyword">int</span> size)</span></span>&#123;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; size; i++) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> j = i; j &gt; <span class="number">0</span> &amp;&amp; arr[j] &lt; arr[j - <span class="number">1</span>]; j--) &#123;<span class="comment">//别忘了防止越界的问题，j&gt;0。</span></span><br><span class="line">            <span class="keyword">int</span> temp = arr[j-<span class="number">1</span>];</span><br><span class="line">            arr[j-<span class="number">1</span>] = arr[j];</span><br><span class="line">            arr[j] = temp;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="选择排序"><a href="#选择排序" class="headerlink" title="选择排序"></a>选择排序</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//每次把未排序中最小的数选出来，然后和前面未排序第一个数交换。</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">select_sort</span><span class="params">(<span class="keyword">int</span>[] arr,<span class="keyword">int</span> right)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> small;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; right - <span class="number">1</span>; i++) &#123;<span class="comment">//这里写成right也是没有问题的，但是right的话理论上来说多做了一步无用功</span></span><br><span class="line">        small = i;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> j = i + <span class="number">1</span>; j &lt; right; j++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (arr[j] &lt; arr[small]) &#123;</span><br><span class="line">                <span class="keyword">int</span> temp = arr[j];</span><br><span class="line">                arr[j] = arr[small];</span><br><span class="line">                arr[small] = temp;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="归并排序"><a href="#归并排序" class="headerlink" title="归并排序"></a>归并排序</h2><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">归并排序采用了分治的思想。将数字分成许多小块，每块排序，然后再把块逐步合并起来。</span></span><br><span class="line"><span class="comment">重点：最终合并的时候需要一个临时数组来存储合并数据。合并的时候左右两边是两个排好序的数组，现在要把它们组合起来。关键点就在于判断每一次放入临时数组的是左侧还是右侧的数据。</span></span><br><span class="line"><span class="comment">first和second代表左右侧</span></span><br><span class="line"><span class="comment">如果左侧比右侧小，而且此时两个数组都没越界，左侧的数输入到temp。</span></span><br><span class="line"><span class="comment">如果左侧越界，那么右侧读入。</span></span><br><span class="line"><span class="comment">如果右侧越界，那么左侧读入。</span></span><br><span class="line"><span class="comment">综合起来，读入左侧数据的条件即为右侧越界或者左侧没越界且左侧比右侧小。</span></span><br><span class="line"><span class="comment">最后再改变nums</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">merge_sort</span><span class="params">(vector&lt;<span class="keyword">int</span>&gt; &amp;nums, <span class="keyword">int</span> left, <span class="keyword">int</span> right, vector&lt;<span class="keyword">int</span>&gt; &amp;temp)</span></span></span><br><span class="line"><span class="function"></span>&#123;<span class="comment">//C++版本</span></span><br><span class="line">    <span class="keyword">if</span> (left + <span class="number">1</span> &gt;= right) &#123;</span><br><span class="line">       <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> mid = left + (right - left) / <span class="number">2</span>;<span class="comment">//寻找中间数的位置</span></span><br><span class="line"></span><br><span class="line">    <span class="built_in">merge_sort</span>(nums, left, mid, temp);<span class="comment">//左侧递归</span></span><br><span class="line">    <span class="built_in">merge_sort</span>(nums, mid, right, temp);<span class="comment">//右侧递归</span></span><br><span class="line"></span><br><span class="line">   <span class="keyword">int</span> first = left, second = mid, i = left;</span><br><span class="line">   <span class="keyword">while</span> (first &lt; mid || second &lt; right) &#123;   <span class="comment">//first是左侧边界开始，second是右侧边界开始</span></span><br><span class="line">    <span class="keyword">if</span> (second &gt;= r || (nums[first] &lt;= nums[second] &amp;&amp; first &lt; mid)) &#123;<span class="comment">//右侧越界或者是 左侧没有越界，并且左侧的first位置比右侧的second位置小</span></span><br><span class="line">        temp[i++] = nums[first++];<span class="comment">//那就左侧写入temp</span></span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        temp[i++] = nums[second++];</span><br><span class="line">    &#125;</span><br><span class="line">   &#125;</span><br><span class="line">   <span class="keyword">for</span> (i = l; i &lt; r; ++i) &#123;</span><br><span class="line">        nums[i] = temp[i];</span><br><span class="line">   &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//java</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">merge_sort</span><span class="params">(<span class="keyword">int</span>[] arr,<span class="keyword">int</span> left, <span class="keyword">int</span> right, <span class="keyword">int</span>[] temp)</span> </span>&#123;<span class="comment">//左闭右开区间哦，所以right进来是size</span></span><br><span class="line">    <span class="keyword">if</span> (left + <span class="number">1</span> &gt;= right) &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> mid = left + (right - left) / <span class="number">2</span>;</span><br><span class="line">    merge_sort(arr, left, mid, temp);<span class="comment">//别忘了左闭右开区间</span></span><br><span class="line">    merge_sort(arr, mid, right, temp);</span><br><span class="line">    <span class="keyword">int</span> first = left, second = mid, i = left;</span><br><span class="line">    <span class="keyword">while</span> (first &lt; mid || second &lt; right) &#123;</span><br><span class="line">        <span class="keyword">if</span> (second &gt;= right || (arr[first] &lt;= arr[second] &amp;&amp; first &lt; mid)) &#123;</span><br><span class="line">            temp[i++] = arr[first++];</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            temp[i++] = arr[second++];</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (i = left; i &lt; right; i++) &#123;</span><br><span class="line">        arr[i] = temp[i];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>下面画图理解递归是怎么操作的。<br><img src="/images/leetcode-java/4-4.jpg" alt="归并排序"></p>
<h2 id="冒泡排序"><a href="#冒泡排序" class="headerlink" title="冒泡排序"></a>冒泡排序</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">bubble_sort</span><span class="params">(<span class="keyword">int</span>[] arr,<span class="keyword">int</span> right)</span> </span>&#123;<span class="comment">//每一轮把最大的一个数沉下去，下一轮就可以不用比较前一轮最后一个数</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>; i &lt; right; i++) &#123;<span class="comment">//这个是从1开始</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">1</span>; j &lt; right - i + <span class="number">1</span>; j++) &#123;<span class="comment">//不用再比较前一轮的最后一个数，size-i+1</span></span><br><span class="line">            <span class="keyword">if</span> (arr[j] &lt; arr[j - <span class="number">1</span>]) &#123;<span class="comment">//因为和前一个比较，所以一开始的i起始位置是1</span></span><br><span class="line">                <span class="keyword">int</span> temp = arr[j];</span><br><span class="line">                arr[j] = arr[j - <span class="number">1</span>];</span><br><span class="line">                arr[j - <span class="number">1</span>] = temp;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="215-数组中的第K个最大元素-medium"><a href="#215-数组中的第K个最大元素-medium" class="headerlink" title="215 数组中的第K个最大元素 medium"></a>215 数组中的第K个最大元素 medium</h2><p>这个题结合1738来看。思路：寻找第K个大的元素，可以用快速排序法，快速排序就是每次选择一个枢轴元素，然后比他小的在左边，比他大的在右边，最终可以确定枢轴元素的最终位置。对比这个位置和第K大的位置，如果比这个位置小，就在左边递归，反之右边递归。需要注意一个点，就是选择枢轴元素要随机选，不然会遇到极端案例，导致时间复杂度高。当然本题实际执行只考虑了比枢轴元素大的数以及把大的元素放在左边，是为了符合题目第k大的元素，注意本题解法也是一开始把枢轴元素放在最右边。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//Math.random()*(n-m)+m，生成大于等于m小于n的随机数</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">findKthLargest</span><span class="params">(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> quickSelect(nums, <span class="number">0</span>, k - <span class="number">1</span>, nums.length - <span class="number">1</span>);<span class="comment">//第k大的位置也就是数组中k-1的位置</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="keyword">int</span> <span class="title">quickSelect</span><span class="params">(<span class="keyword">int</span>[] arr, <span class="keyword">int</span> left, <span class="keyword">int</span> kth, <span class="keyword">int</span> right)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> curPartition = partition(arr, left, right);</span><br><span class="line">        <span class="keyword">if</span> (curPartition == kth) &#123;</span><br><span class="line">            <span class="keyword">return</span> arr[curPartition];</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span> (curPartition &lt; kth) &#123;</span><br><span class="line">            <span class="keyword">return</span> quickSelect(arr, curPartition + <span class="number">1</span>, kth, right);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> quickSelect(arr, left, kth, curPartition - <span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="keyword">int</span> <span class="title">partition</span><span class="params">(<span class="keyword">int</span>[] arr, <span class="keyword">int</span> left, <span class="keyword">int</span> right)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> pivotIndex = left + (<span class="keyword">int</span>)(Math.random() * (right - left + <span class="number">1</span>));<span class="comment">//生成大于等于left小于等于right的随机数</span></span><br><span class="line">        swap(arr, pivotIndex, right);<span class="comment">//先把随机抽中的数与最右边的数交换。</span></span><br><span class="line">        <span class="keyword">int</span> index = left - <span class="number">1</span>;<span class="comment">//把index初始化，一开始应该是-1。</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = left; i &lt; right; i++) &#123;<span class="comment">//在区间范围内寻找</span></span><br><span class="line">            <span class="keyword">if</span> (arr[i] &gt;= arr[right]) &#123;<span class="comment">//因为这个题说找最大的第k个数，所以只需要关注比这个枢轴元素大的数</span></span><br><span class="line">                index += <span class="number">1</span>;<span class="comment">//因为index一开始是-1</span></span><br><span class="line">                swap(arr, index, i);<span class="comment">//出现大于枢轴元素的数，就从左到右开始放。</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        index += <span class="number">1</span>;<span class="comment">//index加1，是为了下一步操作，把枢轴元素放到正确的位置</span></span><br><span class="line">        swap(arr, index, right);<span class="comment">//结束这个步骤，枢轴元素左边都是大于它的数，右边都是小于它的数</span></span><br><span class="line">        <span class="keyword">return</span> index;<span class="comment">//返回随机抽中枢轴元素的位置</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">swap</span><span class="params">(<span class="keyword">int</span>[] arr, <span class="keyword">int</span> l, <span class="keyword">int</span> r)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> temp = arr[l];</span><br><span class="line">        arr[l] = arr[r];</span><br><span class="line">        arr[r] = temp;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*写法2，自我感觉这种写法更好看</span></span><br><span class="line"><span class="comment">    private int partition(int[] arr, int left, int right) &#123;</span></span><br><span class="line"><span class="comment">        int pivotIndex = left + (int)(Math.random() * (right - left + 1));</span></span><br><span class="line"><span class="comment">        swap(arr, pivotIndex, right);</span></span><br><span class="line"><span class="comment">        int index = left;//这里改变了</span></span><br><span class="line"><span class="comment">        for (int i = left; i &lt; right; i++) &#123;</span></span><br><span class="line"><span class="comment">            if (arr[i] &gt;= arr[right]) &#123;</span></span><br><span class="line"><span class="comment">                swap(arr, index, i);</span></span><br><span class="line"><span class="comment">                index += 1;//这里改变了</span></span><br><span class="line"><span class="comment">            &#125;</span></span><br><span class="line"><span class="comment">        &#125;</span></span><br><span class="line"><span class="comment">        //这里删除了</span></span><br><span class="line"><span class="comment">        swap(arr, index, right);</span></span><br><span class="line"><span class="comment">        return index;</span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//这个版本就是我们平时理解的快速排序。但是这个版本每次跑起来的速度和占用内存都不如上面那个好。</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">findKthLargest</span><span class="params">(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> quickSelect(nums, <span class="number">0</span>, k - <span class="number">1</span>, nums.length - <span class="number">1</span>);<span class="comment">//第k大的位置也就是数组中k-1的位置</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="keyword">int</span> <span class="title">quickSelect</span><span class="params">(<span class="keyword">int</span>[] arr, <span class="keyword">int</span> left, <span class="keyword">int</span> kth, <span class="keyword">int</span> right)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> curPartition = partition(arr, left, right);</span><br><span class="line">        <span class="keyword">if</span> (curPartition == kth) &#123;</span><br><span class="line">            <span class="keyword">return</span> arr[curPartition];</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span> (curPartition &lt; kth) &#123;</span><br><span class="line">            <span class="keyword">return</span> quickSelect(arr, curPartition + <span class="number">1</span>, kth, right);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> quickSelect(arr, left, kth, curPartition - <span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="keyword">int</span> <span class="title">partition</span><span class="params">(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> left, <span class="keyword">int</span> right)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> pivotIndex = left + (<span class="keyword">int</span>)(Math.random() * (right - left + <span class="number">1</span>));<span class="comment">//生成大于等于left小于等于right的随机数</span></span><br><span class="line">        swap(nums, pivotIndex, left);<span class="comment">//先把随机抽中的数与最右边的数交换。</span></span><br><span class="line">        <span class="keyword">int</span> first = left, last = right, key = nums[first];<span class="comment">//注意这里是last = right ，而不是right-1，因为上面已经处理好边界是lenght-1</span></span><br><span class="line">        <span class="keyword">while</span> (first &lt; last) &#123;</span><br><span class="line">            <span class="keyword">while</span> (first &lt; last &amp;&amp; nums[last] &lt;= key) &#123;<span class="comment">//这里是从右边扫描，小于的不管</span></span><br><span class="line">                --last;</span><br><span class="line">            &#125;</span><br><span class="line">            nums[first] = nums[last];<span class="comment">//大于的就把这个数放到前面，这样可以符合题目第K大的条件</span></span><br><span class="line">            <span class="keyword">while</span> (first &lt; last &amp;&amp; nums[first] &gt;= key) &#123;</span><br><span class="line">                ++first;</span><br><span class="line">            &#125;</span><br><span class="line">            nums[last] = nums[first];</span><br><span class="line">        &#125;</span><br><span class="line">        nums[first] = key;</span><br><span class="line">        <span class="keyword">return</span> first;&#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">swap</span><span class="params">(<span class="keyword">int</span>[] arr, <span class="keyword">int</span> l, <span class="keyword">int</span> r)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> temp = arr[l];</span><br><span class="line">        arr[l] = arr[r];</span><br><span class="line">        arr[r] = temp;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="347-前K个高频元素-桶排序-medium"><a href="#347-前K个高频元素-桶排序-medium" class="headerlink" title="347 前K个高频元素(桶排序) medium"></a>347 前K个高频元素(桶排序) medium</h2><p>首先用hash来创建一个key，value(频率)对应。然后再创建一个list，把相同频率的放在一个位置。最后从后往前面取出前k个来。也就是桶的思想。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">知识点</span></span><br><span class="line"><span class="comment">1.LinkedHashMap继承于HashMap,是基于HashMap和双向链表实现的</span></span><br><span class="line"><span class="comment">2.HashMap无序，LinkedHashMap有序，分为插入顺序和访问顺序</span></span><br><span class="line"><span class="comment">3.访问顺序操作的时候，put和get操作已存在的Entry时，都会把Entry移动到双向链表的表尾(也就是先删除再插入)</span></span><br><span class="line"><span class="comment">4.LinkedHashMap存取数据，还是跟HashMap一样使用Entry的方式，双向链表只是为了保证顺序</span></span><br><span class="line"><span class="comment">5.LinkenHashMap线程是不安全的</span></span><br><span class="line"><span class="comment">部分操作：</span></span><br><span class="line"><span class="comment">LinkedHashMap&lt;Integer,Integer&gt; map = new LinkedHashMap&lt;&gt;();//创建map</span></span><br><span class="line"><span class="comment">map.put(key,value)//存入key和value</span></span><br><span class="line"><span class="comment">map.get(key)//取出value</span></span><br><span class="line"><span class="comment">map.keySet()//打印的话是输出key的顺序</span></span><br><span class="line"><span class="comment">map.getOrDefault(Object key, V defaultValue)方法的作用是：当Map集合中有这个key时，就使用这个key值；如果没有就使用默认值defaultValue。</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">1.数组也就是Array（[]）：最高效；但是其容量固定且无法动态改变；使用时候 new和不new没有区别</span></span><br><span class="line"><span class="comment">2.ArrayList：容量可动态增长；但牺牲效率；详细见https://www.runoob.com/java/java-arraylist.html</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">int</span>[] topKFrequent(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> k) &#123;</span><br><span class="line">        LinkedHashMap&lt;Integer,Integer&gt; map = <span class="keyword">new</span> LinkedHashMap&lt;&gt;();<span class="comment">//以key,value来保存，本题key就是数字本身，value就是频率</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; nums.length; i++) &#123;<span class="comment">//创建一个map来对应数字和频率</span></span><br><span class="line">            <span class="keyword">if</span> (map.containsKey(nums[i])) &#123;<span class="comment">//如果map中的key存在value</span></span><br><span class="line">                map.put(nums[i], map.get(nums[i]) + <span class="number">1</span>);<span class="comment">//注意不是map.get(nums[i] + 1)。从第二次开始就在基础频率上增加1</span></span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                map.put(nums[i],<span class="number">1</span>);<span class="comment">//第一次大家都是空的，直接走这一步创建频率为1。</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        List&lt;Integer&gt;[] ans=<span class="keyword">new</span> List[nums.length + <span class="number">1</span>];<span class="comment">//这个处理方式比较随意，会出现很多的null，至于多加1，举个例子把。[2,2]。这个2的频率是2。然后代码下面取的时候是ans[2(频率)]，但是我们知道下标如果是用length的话只有0,1。所以这个基础上加1。</span></span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> num: map.keySet())&#123;<span class="comment">//把map中的key依次按顺序处理</span></span><br><span class="line">            <span class="keyword">int</span> i=map.get(num);<span class="comment">//取出这个Key对应的value(频率)</span></span><br><span class="line">            <span class="keyword">if</span>(ans[i]==<span class="keyword">null</span>)&#123;</span><br><span class="line">                ans[i]=<span class="keyword">new</span> ArrayList&lt;&gt;();<span class="comment">//初始化，ans一开始本来就是空的嘛</span></span><br><span class="line">            &#125;</span><br><span class="line">            ans[i].add(num);<span class="comment">//同频率的key添加到同一个位置的ans中</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">int</span> res[] = <span class="keyword">new</span> <span class="keyword">int</span>[k];<span class="comment">//设置一个数组，长度为k</span></span><br><span class="line">        <span class="keyword">int</span> count = <span class="number">0</span>;<span class="comment">//计数器</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = ans.length - <span class="number">1</span>; i &gt;= <span class="number">0</span> &amp;&amp; count &lt;k; i--) &#123;<span class="comment">//注意这里是ans.length，而不是nums.length。从后往前面操作，因为题目说是频率的前k个</span></span><br><span class="line">            <span class="keyword">if</span> (ans[i] != <span class="keyword">null</span>) &#123;<span class="comment">//对ans中有数字的操作</span></span><br><span class="line">                <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt; ans[i].size(); j++) &#123;<span class="comment">//然后取出这个位置中的ans</span></span><br><span class="line">                    <span class="keyword">if</span> (count &lt; k) &#123;</span><br><span class="line">                        res[count++] = ans[i].get(j);<span class="comment">//题目数据保证答案唯一，换句话说，数组中前 k 个高频元素的集合是唯一的.也就是如果题目要求k是2。但是频率最高的同时有3个数，这个是不成立的，也就不存在这个样例。所以每放进一个数，count就要增加1.</span></span><br><span class="line">                    &#125; <span class="keyword">else</span> <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//这个解法稍微改了一点点，可以避免在生成bucket是时候浪费空间，能省一点是一点，但是实际测试的时候大家好像差不多，可能没有出现极端情况。</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">int</span>[] topKFrequent(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> k) &#123;</span><br><span class="line">        LinkedHashMap&lt;Integer,Integer&gt; map = <span class="keyword">new</span> LinkedHashMap&lt;&gt;();</span><br><span class="line">        <span class="keyword">int</span> frequency = <span class="number">0</span>;<span class="comment">//频率计算</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; nums.length; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (map.containsKey(nums[i])) &#123;</span><br><span class="line">                map.put(nums[i], map.get(nums[i]) + <span class="number">1</span>);</span><br><span class="line">                frequency = Math.max(map.get(nums[i]),frequency);<span class="comment">//找到最高频率</span></span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                map.put(nums[i],<span class="number">1</span>);</span><br><span class="line">                frequency = Math.max(map.get(nums[i]),frequency);<span class="comment">//找到最高频率</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        List&lt;Integer&gt;[] ans=<span class="keyword">new</span> List[frequency + <span class="number">1</span>];<span class="comment">//长度只需要频率+1.这样可以避免上面的解法，省空间！！！</span></span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> num: map.keySet())&#123;</span><br><span class="line">            <span class="keyword">int</span> i=map.get(num);</span><br><span class="line">            <span class="keyword">if</span>(ans[i]==<span class="keyword">null</span>)&#123;</span><br><span class="line">                ans[i]=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">            &#125;</span><br><span class="line">            ans[i].add(num);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">int</span> res[] = <span class="keyword">new</span> <span class="keyword">int</span>[k];</span><br><span class="line">        <span class="keyword">int</span> count = <span class="number">0</span>;<span class="comment">//计数器</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = ans.length - <span class="number">1</span>; i &gt;= <span class="number">0</span> &amp;&amp; count &lt;k; i--) &#123;</span><br><span class="line">            <span class="keyword">if</span> (ans[i] != <span class="keyword">null</span>) &#123;<span class="comment">//对ans中有数字的操作</span></span><br><span class="line">                <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt; ans[i].size(); j++) &#123;</span><br><span class="line">                    <span class="keyword">if</span> (count &lt; k) &#123;</span><br><span class="line">                        res[count++] = ans[i].get(j);</span><br><span class="line">                    &#125; <span class="keyword">else</span> <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="451-根据字符出现频率排序-桶排序-medium"><a href="#451-根据字符出现频率排序-桶排序-medium" class="headerlink" title="451 根据字符出现频率排序(桶排序) medium"></a>451 根据字符出现频率排序(桶排序) medium</h2><p>这个题主要和上一题对比的话，我觉得主要是一些语法上，比如对字符处理和上一题对数字的处理是不太一样的。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">frequencySort</span><span class="params">(String s)</span> </span>&#123;</span><br><span class="line">        Map&lt;Character,Integer&gt; map = <span class="keyword">new</span> HashMap&lt;Character,Integer&gt;();</span><br><span class="line">        <span class="keyword">int</span> maxfreq = <span class="number">0</span>;<span class="comment">//找出最高的频率</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; s.length(); i++) &#123;</span><br><span class="line">            <span class="keyword">char</span> c = s.charAt(i);</span><br><span class="line">            <span class="keyword">int</span> frequency = map.getOrDefault(c, <span class="number">0</span>) + <span class="number">1</span>;<span class="comment">//有就在频率的基础上加1，没有就默认0。</span></span><br><span class="line">            map.put(c, frequency);<span class="comment">//放入hash中</span></span><br><span class="line">            maxfreq = Math.max(maxfreq, frequency);<span class="comment">//找到频率最大值</span></span><br><span class="line">        &#125;</span><br><span class="line">        StringBuffer[] buckets = <span class="keyword">new</span> StringBuffer[maxfreq + <span class="number">1</span>];</span><br><span class="line">         <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt;= maxfreq; i++) &#123;</span><br><span class="line">            buckets[i] = <span class="keyword">new</span> StringBuffer();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//Map.entrySet() 这个方法返回的是一个Set&lt;Map.Entry&lt;K,V&gt;&gt;,Map.Entry里有相应的getKey和getValue方法</span></span><br><span class="line">        <span class="keyword">for</span> (Map.Entry&lt;Character, Integer&gt; entry : map.entrySet()) &#123;<span class="comment">//这个写法和上一题的不同之处。上一题都是整数，比较好处理。这个是字符，这样处理比较方便。</span></span><br><span class="line">            <span class="keyword">char</span> c = entry.getKey();<span class="comment">//注意是getkey</span></span><br><span class="line">            <span class="keyword">int</span> frequency = entry.getValue();<span class="comment">//注意是getvalue</span></span><br><span class="line">            buckets[frequency].append(c); </span><br><span class="line">        &#125;</span><br><span class="line">        StringBuffer sb =<span class="keyword">new</span> StringBuffer();</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = maxfreq; i &gt; <span class="number">0</span>; i--) &#123;</span><br><span class="line">            StringBuffer bucket = buckets[i];</span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt; bucket.length(); j++) &#123;</span><br><span class="line">                <span class="keyword">for</span> (<span class="keyword">int</span> k = <span class="number">0</span>; k &lt; i; k++) &#123;</span><br><span class="line">                    sb.append(bucket.charAt(j));</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;             </span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> sb.toString();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="75-颜色分类-medium"><a href="#75-颜色分类-medium" class="headerlink" title="75 颜色分类 medium"></a>75 颜色分类 medium</h2><p>直接插入排序，但是貌似速度和内存都不占优势？</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">sortColors</span><span class="params">(<span class="keyword">int</span>[] nums)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; nums.length; i++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> j = i; j &gt; <span class="number">0</span> &amp;&amp; nums[j] &lt; nums[j-<span class="number">1</span>]; j--) &#123;</span><br><span class="line">                <span class="keyword">int</span> temp = nums[j];</span><br><span class="line">                nums[j] = nums[j - <span class="number">1</span>];</span><br><span class="line">                nums[j - <span class="number">1</span>] = temp;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h1 id="一切皆可搜索"><a href="#一切皆可搜索" class="headerlink" title="一切皆可搜索"></a>一切皆可搜索</h1><h2 id="695-岛屿的最大面积-DFS-medium"><a href="#695-岛屿的最大面积-DFS-medium" class="headerlink" title="695 岛屿的最大面积(DFS) medium"></a>695 岛屿的最大面积(DFS) medium</h2><p>思路是深度优先遍历，分为主函数和辅助函数，主函数就是遍历每个点的位置，辅助函数就是dfs，设置好不满足的条件，满足条件的继续搜索。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">maxAreaOfIsland</span><span class="params">(<span class="keyword">int</span>[][] grid)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> ans = <span class="number">0</span>;<span class="comment">//最大数量初始化为0</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; grid.length; i++) &#123;<span class="comment">//表示一共有多少行（也就是每列的长度，可以理解为Y，注意就是YYYYY）</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt; grid[<span class="number">0</span>].length; j++) &#123; <span class="comment">//表示一共有多少列（也就是每行的长度，可以理解为X，注意就是XXXXX）</span></span><br><span class="line">                ans = Math.max(ans, dfs(grid, i, j));<span class="comment">//比较目前的岛屿是否最大，若不是，就替换为最大岛屿</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    <span class="keyword">return</span> ans;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span>[][] grid, <span class="keyword">int</span> cur_i, <span class="keyword">int</span> cur_j)</span> </span>&#123;</span><br><span class="line">        <span class="comment">//这个非常重要，是深度优先搜索的不满足条件。有超过边界的(i和j小于0；i等于列长度，j等于行长度，注意数组的开始位置是0哦；还有当前是海洋，也就是不是陆地的地方就不搜索)</span></span><br><span class="line">        <span class="keyword">if</span> (cur_i &lt; <span class="number">0</span> || cur_j &lt; <span class="number">0</span> || cur_i == grid.length || cur_j == grid[<span class="number">0</span>].length || grid[cur_i][cur_j] != <span class="number">1</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        grid[cur_i][cur_j] = <span class="number">0</span>;<span class="comment">//当上面的条件都跳过了，也就是我们找到了一个陆地，这时候把他置为0，表示我们已经搜索过这个陆地了，然后开始上下左右搜索，不然应该会死循环。</span></span><br><span class="line">        <span class="comment">//这样可以组成 （0,1）（1,0）（-1,0）（0,-1）四种情况。</span></span><br><span class="line">        <span class="keyword">int</span>[] index_i = &#123;<span class="number">0</span>, <span class="number">0</span>, <span class="number">1</span>, -<span class="number">1</span>&#125;;</span><br><span class="line">        <span class="keyword">int</span>[] index_j = &#123;<span class="number">1</span>, -<span class="number">1</span>, <span class="number">0</span>, <span class="number">0</span>&#125;;</span><br><span class="line">        <span class="keyword">int</span> ans = <span class="number">1</span>;<span class="comment">//陆地的数量初始为1</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> index = <span class="number">0</span>; index &lt; <span class="number">4</span>; index++) &#123;<span class="comment">//遍历4次，走4个方向</span></span><br><span class="line">            <span class="keyword">int</span> next_inedx_i = cur_i + index_i[index];</span><br><span class="line">            <span class="keyword">int</span> next_inedx_j = cur_j + index_j[index];</span><br><span class="line">            ans += dfs(grid, next_inedx_i, next_inedx_j);<span class="comment">//把连起来的陆地加起来 </span></span><br><span class="line">        &#125;</span><br><span class="line">    <span class="keyword">return</span> ans;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">/*对于二维数组解释下长度问题</span></span><br><span class="line"><span class="comment">grid.length = 8 (8个一维数组，表示有多少行，也可以表示为每列的长度)</span></span><br><span class="line"><span class="comment">grid[0].length = 13（1个数组中有13个数，表示有多少列，也可以表示为每行的长度）</span></span><br><span class="line"><span class="comment">[[0,0,1,0,0,0,0,1,0,0,0,0,0],</span></span><br><span class="line"><span class="comment">[0,0,0,0,0,0,0,1,1,1,0,0,0],</span></span><br><span class="line"><span class="comment">[0,1,1,0,1,0,0,0,0,0,0,0,0],</span></span><br><span class="line"><span class="comment">[0,1,0,0,1,1,0,0,1,0,1,0,0],</span></span><br><span class="line"><span class="comment">[0,1,0,0,1,1,0,0,1,1,1,0,0],</span></span><br><span class="line"><span class="comment">[0,0,0,0,0,0,0,0,0,0,1,0,0],</span></span><br><span class="line"><span class="comment">[0,0,0,0,0,0,0,1,1,1,0,0,0],</span></span><br><span class="line"><span class="comment">[0,0,0,0,0,0,0,1,1,0,0,0,0]]</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>
<h2 id="547-省份数量-DFS-medium"><a href="#547-省份数量-DFS-medium" class="headerlink" title="547 省份数量(DFS) medium"></a>547 省份数量(DFS) medium</h2><p>做这个题的时候陷入到上一题的思维了，做题还是太少了！本题中有多少个二维数组中有多少个一维数组就代表多少个城市，每个一维数组里面的位置代表本城市(也就是i和j相同)或者其他城市(i和j不一样)，位置上为1代表有连接，也就是大家最后是属于一个省份的。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">思路：设置一个visit数组来表示访问过的城市。</span></span><br><span class="line"><span class="comment">访问第一个点，因为自己本身都是有1的，把visit[0]置为1(表示这个城市已经被访问过了)，这时候就开始深度优先搜索与这个城市相连的城市，然后依次类推，一直没有找到为止，这样就算完成了一个省份的搜索。开始执行下一个visit为0的城市访问。</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">findCircleNum</span><span class="params">(<span class="keyword">int</span>[][] isConnected)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> citys = isConnected.length;<span class="comment">//表示一共有多少个</span></span><br><span class="line">        <span class="keyword">boolean</span>[] visited = <span class="keyword">new</span> <span class="keyword">boolean</span>[citys];<span class="comment">//全部城市访问都置为0</span></span><br><span class="line">        <span class="keyword">int</span> sum = <span class="number">0</span>;<span class="comment">//省份数量初始为0</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; citys; i++) &#123;<span class="comment">//开始搜索啦</span></span><br><span class="line">            <span class="keyword">if</span>(!visited[i]) &#123;<span class="comment">//只针对没有被访问的城市进行搜索</span></span><br><span class="line">                dfs(isConnected, visited, citys, i);</span><br><span class="line">                sum++;<span class="comment">//上面全部搜索完，就相当于找到一个省份</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    <span class="keyword">return</span> sum;</span><br><span class="line">&#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span>[][] isConnected,<span class="keyword">boolean</span>[] visited, <span class="keyword">int</span> citys, <span class="keyword">int</span> i)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt; citys; j++) &#123;<span class="comment">//i是固定的，然后逐个位置搜索看是否有1</span></span><br><span class="line">            <span class="keyword">if</span> (!visited[j] &amp;&amp; isConnected[i][j] == <span class="number">1</span>) &#123;<span class="comment">//满足条件是位置上为1，已经这个城市没有被搜索过</span></span><br><span class="line">                visited[j] = <span class="keyword">true</span>;<span class="comment">//满足了上面条件，记得把这个城市置为1，表示已经搜索过了</span></span><br><span class="line">                dfs(isConnected, visited, citys, j);<span class="comment">//开始搜索与i相连的城市，注意这里最后是jjjj。</span></span><br><span class="line">                <span class="comment">//所以，只要说一个城市被搜索过了，这个城市所有的连接情况我们都找到了，也就是他们是属于一个省份的。</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="417-太平洋大西洋水流问题-DFS-medium"><a href="#417-太平洋大西洋水流问题-DFS-medium" class="headerlink" title="!417 太平洋大西洋水流问题(DFS) medium"></a>!417 太平洋大西洋水流问题(DFS) medium</h2><p>一开始看了半天例子，以为那几点是形成河流的样子。ok，现在说下题目意思，是找出所有的点，这个点可以流向太平洋，也能流向大西洋 ，所以看例子的时候，单独看每一个点，然后需要自己画出流动方向。<br>!代表我在<a target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/pacific-atlantic-water-flow/solution/shen-du-sou-suo-dfsxi-wang-ke-yi-yong-zu-65si/">Leetcode</a>上写题解了，哈哈。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; pacificAtlantic(<span class="keyword">int</span>[][] heights) &#123;</span><br><span class="line">        <span class="keyword">int</span> n = heights.length;<span class="comment">//二维数组的行数</span></span><br><span class="line">        <span class="keyword">int</span> m = heights[<span class="number">0</span>].length;<span class="comment">//二维数据的列数</span></span><br><span class="line">        <span class="keyword">boolean</span>[][] can_reach_p = <span class="keyword">new</span> <span class="keyword">boolean</span>[n][m];<span class="comment">//初始化可以到达太平洋的数组</span></span><br><span class="line">        <span class="keyword">boolean</span>[][] can_reach_a = <span class="keyword">new</span> <span class="keyword">boolean</span>[n][m];<span class="comment">//初试化可以到达大西洋的数组</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">            dfs(heights, i, <span class="number">0</span>, can_reach_p);<span class="comment">//搜索左列，也就是靠近太平洋</span></span><br><span class="line">            dfs(heights, i, m - <span class="number">1</span>, can_reach_a);<span class="comment">//搜索右列，也就是靠近大西洋</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt; m; j++) &#123;</span><br><span class="line">            dfs(heights, <span class="number">0</span>, j, can_reach_p);<span class="comment">//搜索上列，也就是靠近太平洋</span></span><br><span class="line">            dfs(heights, n - <span class="number">1</span>, j, can_reach_a);<span class="comment">//搜索下列，也就是靠近大西洋</span></span><br><span class="line">        &#125;</span><br><span class="line">        List&lt;List&lt;Integer&gt;&gt; res = <span class="keyword">new</span> ArrayList&lt;&gt;();<span class="comment">//初始化一个list来保存符合条件的坐标</span></span><br><span class="line">        <span class="comment">//全部坐标进行判断</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt; m; j++) &#123;</span><br><span class="line">                <span class="keyword">if</span> (can_reach_a[i][j] &amp;&amp; can_reach_p[i][j]) &#123;<span class="comment">//判断这个坐标是否同时流向太平洋和大西洋</span></span><br><span class="line">                    res.add(List.of(i, j));</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">     </span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span>[][] heights, <span class="keyword">int</span> i, <span class="keyword">int</span> j, <span class="keyword">boolean</span>[][] can_reach)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (can_reach[i][j] == <span class="keyword">true</span>) &#123;<span class="comment">//如果这个坐标是1，就说明人家早就满足条件了，不需要再进行深度搜索了</span></span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        can_reach[i][j] = <span class="keyword">true</span>;<span class="comment">//首先把这个坐标给置为1，代表可以达到海洋</span></span><br><span class="line">        <span class="comment">//因为坐标只能进行上下左右移动，也就是(0,1),(0,-1),(1,0),(-1,0)。所以设置成下面这种格式</span></span><br><span class="line">        <span class="keyword">int</span>[] index_i = &#123;<span class="number">0</span>, <span class="number">0</span>, <span class="number">1</span>, -<span class="number">1</span>&#125;;</span><br><span class="line">        <span class="keyword">int</span>[] index_j = &#123;<span class="number">1</span>, -<span class="number">1</span>, <span class="number">0</span>, <span class="number">0</span>&#125;;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> index = <span class="number">0</span>; index &lt; <span class="number">4</span>; index++) &#123;<span class="comment">//上下左右4次坐标都要判断</span></span><br><span class="line">            <span class="keyword">int</span> next_index_i = i + index_i[index];<span class="comment">//设置下一个坐标的i</span></span><br><span class="line">            <span class="keyword">int</span> next_index_j = j + index_j[index];<span class="comment">//设置下一个坐标的j</span></span><br><span class="line">            <span class="comment">//需要满足下面的条件才能进行深度搜索，不能超过边界，还有下一个坐标要比原来坐标大或者相等。</span></span><br><span class="line">            <span class="keyword">if</span> (next_index_i &gt;= <span class="number">0</span> &amp;&amp; next_index_i &lt; heights.length &amp;&amp; next_index_j &gt;= <span class="number">0</span> &amp;&amp; next_index_j &lt; heights[<span class="number">0</span>].length &amp;&amp; heights[i][j] &lt;= heights[next_index_i][next_index_j]) &#123;</span><br><span class="line">                            dfs(heights, next_index_i, next_index_j, can_reach);</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">        &#125;</span><br><span class="line">    &#125; </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="46-全排列-回溯法-medium"><a href="#46-全排列-回溯法-medium" class="headerlink" title="46 全排列(回溯法) medium"></a>46 全排列(回溯法) medium</h2><p>DFS基本操作：[修改当前节点状态]-&gt;[递归子节点状态]。回溯法：[修改当前节点状态]-&gt;[递归子节点状态]-&gt;[回改当前节点状态]。回溯法是优先搜索的一种特殊状态。一般在排列，组合，选择类问题使用回溯法，这次官方那个视频讲解不错，本题就是按照这个思路来。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">知识点</span><br><span class="line">注意后面的<span class="keyword">new</span>的写法</span><br><span class="line">栈：Deque&lt;Integer&gt; path = <span class="keyword">new</span> ArrayDeque&lt;&gt;();</span><br><span class="line">list里面还有一个list： List&lt;List&lt;Integer&gt;&gt; res = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="comment">//状态变量：depth，path，used</span></span><br><span class="line">    <span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; permute(<span class="keyword">int</span>[] nums) &#123;</span><br><span class="line">        List&lt;List&lt;Integer&gt;&gt; res = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">        <span class="keyword">int</span> len = nums.length;</span><br><span class="line">        <span class="keyword">boolean</span>[] used = <span class="keyword">new</span> <span class="keyword">boolean</span>[len];</span><br><span class="line">        <span class="keyword">if</span> (len == <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="comment">//System.out.println(&quot;  res:&quot;+res);</span></span><br><span class="line">            <span class="keyword">return</span> res;</span><br><span class="line">        &#125;</span><br><span class="line">        Deque&lt;Integer&gt; path = <span class="keyword">new</span> ArrayDeque&lt;&gt;();<span class="comment">//栈的应用</span></span><br><span class="line">        dfs(nums, len, <span class="number">0</span>, path, used, res);</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span>[] nums,<span class="keyword">int</span> len, <span class="keyword">int</span> depth, Deque&lt;Integer&gt; path, <span class="keyword">boolean</span>[] used, List&lt;List&lt;Integer&gt;&gt; res)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (depth == len) &#123;</span><br><span class="line">            <span class="comment">/*下面这一句超级超级重要，如果改成res.add(path)。最后输出是[[],[],[],[],[],[]]。</span></span><br><span class="line"><span class="comment">            为什么会这样呢？</span></span><br><span class="line"><span class="comment">            变量 path 所指向的列表 在深度优先遍历的过程中只有一份 ，深度优先遍历完成以后，回到了根结点，成为空列表。</span></span><br><span class="line"><span class="comment">            在 Java 中，参数传递是 值传递，对象类型变量在传参的过程中，复制的是变量的地址。这些地址被添加到 res 变量，但实际上指向的是同一块内存地址，因此我们会看到 6 个空的列表对象。解决的方法很简单，在 res.add(path); 这里做一次拷贝即可。</span></span><br><span class="line"><span class="comment">            */</span></span><br><span class="line">            res.add(<span class="keyword">new</span> ArrayList(path));</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; len; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (used[i] == <span class="keyword">true</span>) &#123; <span class="comment">//如果发现某个位置已经用了，就跳过</span></span><br><span class="line">                <span class="keyword">continue</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            path.addLast(nums[i]);<span class="comment">//栈的添加操作</span></span><br><span class="line">            used[i] = <span class="keyword">true</span>;<span class="comment">//然后把这个位置设置为已经用了</span></span><br><span class="line">            <span class="comment">//System.out.println(&quot;  递归之前 =&gt; &quot; + path+ &quot;  i: &quot; + i + &quot;  used：  &quot; + Arrays.toString(used));</span></span><br><span class="line">            dfs(nums, len, depth + <span class="number">1</span>, path, used, res);<span class="comment">//进行递归操作</span></span><br><span class="line">            used[i] = <span class="keyword">false</span>;<span class="comment">//回改节点状态</span></span><br><span class="line">            path.removeLast();<span class="comment">//回改节点状态，也就是栈的移除操作。</span></span><br><span class="line">            <span class="comment">//System.out.println(&quot;递归之后 =&gt; &quot; + path+ &quot;  i: &quot; + i+ &quot;  used：  &quot; + Arrays.toString(used));</span></span><br><span class="line">        &#125; </span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>下面引用一张<a target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/permutations/solution/hui-su-suan-fa-python-dai-ma-java-dai-ma-by-liweiw/">别人图片</a>来描述这个算法流程。<br><img src="/images/leetcode-java/5-4-1.png" alt="46题全排列1"><br>然后下面这种图片是一些代码流程细节上的理解，注意当代码运行到dfs里面的时候，会回到for，然后for是重新为0的。<br><img src="/images/leetcode-java/5-4-2.png" alt="46题全排列2"></p>
<h2 id="77-组合-回溯法-medium"><a href="#77-组合-回溯法-medium" class="headerlink" title="77 组合(回溯法) medium"></a>77 组合(回溯法) medium</h2><p>注意排列是不重复的，组合是的话[1,2]和[2,1]是一个情况，还有不能对自己组合哦。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line"><span class="comment">//这个写法受到了上一个的影响，不够简洁，实际上完全没有必要用到used，注意有个地方不一样！！！！在唯一一个注释里面！！！</span></span><br><span class="line">    <span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; combine(<span class="keyword">int</span> n, <span class="keyword">int</span> k) &#123;</span><br><span class="line">        <span class="keyword">boolean</span>[] used =<span class="keyword">new</span> <span class="keyword">boolean</span>[n];</span><br><span class="line">        List&lt;List&lt;Integer&gt;&gt; res = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">        <span class="keyword">if</span> (k &lt;= <span class="number">0</span> || n &lt; k) &#123;</span><br><span class="line">            <span class="keyword">return</span> res;</span><br><span class="line">        &#125;</span><br><span class="line">        Deque&lt;Integer&gt; path = <span class="keyword">new</span> ArrayDeque&lt;&gt;();</span><br><span class="line">        <span class="keyword">int</span>[] nums = <span class="keyword">new</span> <span class="keyword">int</span>[n];</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">            nums[i] = i + <span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        dfs(nums, n, k, <span class="number">0</span>, path, used, res);</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> n, <span class="keyword">int</span> k, <span class="keyword">int</span> begin, Deque&lt;Integer&gt; path, <span class="keyword">boolean</span>[] used, List&lt;List&lt;Integer&gt;&gt; res)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (path.size() == k) &#123;</span><br><span class="line">            res.add(<span class="keyword">new</span> ArrayList(path));</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = begin; i &lt; n; i++ ) &#123;</span><br><span class="line">            <span class="keyword">if</span> (used[i] == <span class="keyword">true</span>) &#123;</span><br><span class="line">                <span class="keyword">continue</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            used[i] = <span class="keyword">true</span>;</span><br><span class="line">            path.addLast(nums[i]);</span><br><span class="line">            dfs(nums, n, k, i + <span class="number">1</span>, path, used, res);<span class="comment">//这里不是begin + 1而是i + 1，不然会有重复的组合，因为我们这个题是组合，组合，组合，不是排列！！！！ 比较一下上一题是depth的含义。</span></span><br><span class="line">            used[i] = <span class="keyword">false</span>;</span><br><span class="line">            path.removeLast();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//大佬的简洁解法，还有一个解法会更加省时间，但是不好想，也就是剪枝。具体还是看下面的链接。</span></span><br><span class="line"><span class="keyword">import</span> java.util.ArrayDeque;</span><br><span class="line"><span class="keyword">import</span> java.util.ArrayList;</span><br><span class="line"><span class="keyword">import</span> java.util.Deque;</span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; combine(<span class="keyword">int</span> n, <span class="keyword">int</span> k) &#123;</span><br><span class="line">        List&lt;List&lt;Integer&gt;&gt; res = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">        <span class="keyword">if</span> (k &lt;= <span class="number">0</span> || n &lt; k) &#123;</span><br><span class="line">            <span class="keyword">return</span> res;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 从 1 开始是题目的设定</span></span><br><span class="line">        Deque&lt;Integer&gt; path = <span class="keyword">new</span> ArrayDeque&lt;&gt;();</span><br><span class="line">        dfs(n, k, <span class="number">1</span>, path, res);</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span> n, <span class="keyword">int</span> k, <span class="keyword">int</span> begin, Deque&lt;Integer&gt; path, List&lt;List&lt;Integer&gt;&gt; res)</span> </span>&#123;</span><br><span class="line">        <span class="comment">// 递归终止条件是：path 的长度等于 k</span></span><br><span class="line">        <span class="keyword">if</span> (path.size() == k) &#123;</span><br><span class="line">            res.add(<span class="keyword">new</span> ArrayList&lt;&gt;(path));</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 遍历可能的搜索起点</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = begin; i &lt;= n; i++) &#123;</span><br><span class="line">            <span class="comment">// 向路径变量里添加一个数</span></span><br><span class="line">            path.addLast(i);</span><br><span class="line">            <span class="comment">// 下一轮搜索，设置的搜索起点要加 1，因为组合数理不允许出现重复的元素</span></span><br><span class="line">            dfs(n, k, i + <span class="number">1</span>, path, res);</span><br><span class="line">            <span class="comment">// 重点理解这里：深度优先遍历有回头的过程，因此递归之前做了什么，递归之后需要做相同操作的逆向操作</span></span><br><span class="line">            path.removeLast();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">作者：liweiwei1419</span><br><span class="line">链接：https:<span class="comment">//leetcode-cn.com/problems/combinations/solution/hui-su-suan-fa-jian-zhi-python-dai-ma-java-dai-ma-/</span></span><br><span class="line">来源：力扣（LeetCode）</span><br><span class="line">著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。</span><br></pre></td></tr></table></figure>
<p>用下大佬的图理解这个题<br><img src="/images/leetcode-java/5-5.png" alt="77组合"><br>总结：77题和46题回溯法，一定要先画图！！！看看他们不一样的点，dfs判断加入path的条件，以及在for循环中dfs的写法，这些都是值得注意的。</p>
<h2 id="79-单词搜索-回溯法-medium"><a href="#79-单词搜索-回溯法-medium" class="headerlink" title="79 单词搜索(回溯法) medium"></a>79 单词搜索(回溯法) medium</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">exist</span><span class="params">(<span class="keyword">char</span>[][] board, String word)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> m = board.length;</span><br><span class="line">        <span class="keyword">int</span> n = board[<span class="number">0</span>].length;</span><br><span class="line">        <span class="keyword">boolean</span>[][] visited = <span class="keyword">new</span> <span class="keyword">boolean</span>[m][n];</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; m; i++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt; n; j++) &#123;</span><br><span class="line">                <span class="keyword">boolean</span> flag = backtracking(i, j, board, word, visited, <span class="number">0</span>);</span><br><span class="line">                <span class="keyword">if</span> (flag) &#123;</span><br><span class="line">                    <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">        <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">backtracking</span><span class="params">(<span class="keyword">int</span> i, <span class="keyword">int</span> j, <span class="keyword">char</span>[][] board, String word, <span class="keyword">boolean</span>[][] visited, <span class="keyword">int</span> pos)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (board[i][j] != word.charAt(pos) || visited[i][j] ==<span class="keyword">true</span>) &#123;<span class="comment">//这两个if判断不能对调,因为首先你得判断配对是不是一样的字符，然后才判断他是不是最后一个字符的位置</span></span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span> (pos == word.length() - <span class="number">1</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        visited[i][j] = <span class="keyword">true</span>;</span><br><span class="line">        <span class="keyword">int</span>[] index_i = &#123;<span class="number">0</span>, <span class="number">0</span>, <span class="number">1</span>, -<span class="number">1</span>&#125;;</span><br><span class="line">        <span class="keyword">int</span>[] index_j = &#123;<span class="number">1</span>, -<span class="number">1</span>, <span class="number">0</span>, <span class="number">0</span>&#125;;</span><br><span class="line">        <span class="keyword">boolean</span> result = <span class="keyword">false</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> index = <span class="number">0</span>; index &lt; <span class="number">4</span>; index++) &#123;</span><br><span class="line">            <span class="keyword">int</span> next_index_i = i + index_i[index];<span class="comment">//设置下一个坐标的i</span></span><br><span class="line">            <span class="keyword">int</span> next_index_j = j + index_j[index];<span class="comment">//设置下一个坐标的j</span></span><br><span class="line">            <span class="keyword">if</span> (next_index_i &gt;= <span class="number">0</span> &amp;&amp; next_index_i &lt; board.length &amp;&amp; next_index_j &gt;= <span class="number">0</span> &amp;&amp;  next_index_j &lt; board[<span class="number">0</span>].length) &#123;</span><br><span class="line">                <span class="keyword">boolean</span> flag = backtracking(next_index_i, next_index_j, board, word, visited, pos + <span class="number">1</span>);</span><br><span class="line">                <span class="keyword">if</span> (flag) &#123;</span><br><span class="line">                    result = <span class="keyword">true</span>;</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                &#125;   </span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        visited[i][j] = <span class="keyword">false</span>;</span><br><span class="line">        <span class="keyword">return</span> result;</span><br><span class="line">        &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">/*还可以改成这样，不太喜欢这种写法。</span></span><br><span class="line"><span class="comment">    public boolean backtracking(int i, int j, char[][] board, String word, boolean[][] visited, int pos) &#123;</span></span><br><span class="line"><span class="comment">        //这里改了。</span></span><br><span class="line"><span class="comment">        if (board[i][j] != word.charAt(pos)) &#123;</span></span><br><span class="line"><span class="comment">            return false;</span></span><br><span class="line"><span class="comment">        &#125; else if (pos == word.length() - 1) &#123;</span></span><br><span class="line"><span class="comment">            return true;</span></span><br><span class="line"><span class="comment">        &#125; </span></span><br><span class="line"><span class="comment">        visited[i][j] = true;</span></span><br><span class="line"><span class="comment">        int[] index_i = &#123;0, 0, 1, -1&#125;;</span></span><br><span class="line"><span class="comment">        int[] index_j = &#123;1, -1, 0, 0&#125;;</span></span><br><span class="line"><span class="comment">        boolean result = false;</span></span><br><span class="line"><span class="comment">        for (int index = 0; index &lt; 4; index++) &#123;</span></span><br><span class="line"><span class="comment">            int next_index_i = i + index_i[index];//设置下一个坐标的i</span></span><br><span class="line"><span class="comment">            int next_index_j = j + index_j[index];//设置下一个坐标的j</span></span><br><span class="line"><span class="comment">            if (next_index_i &gt;= 0 &amp;&amp; next_index_i &lt; board.length &amp;&amp; next_index_j &gt;= 0 &amp;&amp;  next_index_j &lt; board[0].length) &#123;</span></span><br><span class="line"><span class="comment">                if (visited[next_index_i][next_index_j] == false) &#123;//这里改了，注意这里是next的判断</span></span><br><span class="line"><span class="comment">                    boolean flag = backtracking(next_index_i, next_index_j, board, word, visited, pos + 1);</span></span><br><span class="line"><span class="comment">                    if (flag) &#123;</span></span><br><span class="line"><span class="comment">                        result = true;</span></span><br><span class="line"><span class="comment">                        break;</span></span><br><span class="line"><span class="comment">                    &#125;</span></span><br><span class="line"><span class="comment">                &#125;</span></span><br><span class="line"><span class="comment">            &#125;</span></span><br><span class="line"><span class="comment">        &#125;</span></span><br><span class="line"><span class="comment">        visited[i][j] = false;</span></span><br><span class="line"><span class="comment">        return result;</span></span><br><span class="line"><span class="comment">        &#125;</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>
<p>下面这个是按照书上思路改写的，但是错误，先放着，未来会修改(已修改，看下面)，初步判断是因为find不是全局变量。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line"><span class="comment">//！！！！这是错误的，错误的！！！正确写法在下一个代码中</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">exist</span><span class="params">(<span class="keyword">char</span>[][] board, String word)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> m = board.length;</span><br><span class="line">        <span class="keyword">int</span> n = board[<span class="number">0</span>].length;</span><br><span class="line">        <span class="keyword">boolean</span>[][] visited = <span class="keyword">new</span> <span class="keyword">boolean</span>[m][n];</span><br><span class="line">        <span class="keyword">boolean</span> find = <span class="keyword">false</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; m; i++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt; n; j++) &#123;</span><br><span class="line">                backtracking(i, j, board, word, find, visited, <span class="number">0</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    <span class="keyword">return</span> find;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">backtracking</span><span class="params">(<span class="keyword">int</span> i, <span class="keyword">int</span> j, <span class="keyword">char</span>[][] board, String word, <span class="keyword">boolean</span> find, <span class="keyword">boolean</span>[][] visited, <span class="keyword">int</span> pos)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (i &lt; <span class="number">0</span> || i &gt;= board.length || j &lt; <span class="number">0</span> ||  j &gt;= board[<span class="number">0</span>].length) &#123;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (board[i][j] != word.charAt(pos) || visited[i][j] || find) &#123;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (pos == word.length() - <span class="number">1</span>) &#123;</span><br><span class="line">            find = <span class="keyword">true</span>;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        visited[i][j] = <span class="keyword">true</span>;</span><br><span class="line">        backtracking(i + <span class="number">1</span>, j, board, word, find, visited, pos + <span class="number">1</span>);</span><br><span class="line">        backtracking(i - <span class="number">1</span>, j, board, word, find, visited, pos + <span class="number">1</span>);</span><br><span class="line">        backtracking(i, j + <span class="number">1</span>, board, word, find, visited, pos + <span class="number">1</span>);</span><br><span class="line">        backtracking(i, j - <span class="number">1</span>, board, word, find, visited, pos + <span class="number">1</span>);</span><br><span class="line">        visited[i][j] = <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//正确写法</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">boolean</span> find = <span class="keyword">false</span>;<span class="comment">//设为全局变量</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">exist</span><span class="params">(<span class="keyword">char</span>[][] board, String word)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(board == <span class="keyword">null</span>) <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">        <span class="keyword">boolean</span>[][] visited = <span class="keyword">new</span> <span class="keyword">boolean</span>[board.length][board[<span class="number">0</span>].length];</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; board.length; i++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt; board[<span class="number">0</span>].length; j++) &#123;</span><br><span class="line">                backTracking(i, j, board, word, visited, <span class="number">0</span>);<span class="comment">//不用传find</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> find;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">backTracking</span><span class="params">(<span class="keyword">int</span> i, <span class="keyword">int</span> j, <span class="keyword">char</span>[][] board, String word, <span class="keyword">boolean</span>[][] visited, <span class="keyword">int</span> pos)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(i &lt; <span class="number">0</span> || i &gt;= board.length || j &lt; <span class="number">0</span> || j &gt;= board[<span class="number">0</span>].length || visited[i][j] || board[i][j] != word.charAt(pos) || find) <span class="keyword">return</span>;</span><br><span class="line">        <span class="keyword">if</span>(pos == word.length() - <span class="number">1</span>) &#123;</span><br><span class="line">            find = <span class="keyword">true</span>;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        visited[i][j] = <span class="keyword">true</span>;</span><br><span class="line">        backTracking(i - <span class="number">1</span>, j, board, word, visited, pos + <span class="number">1</span>);</span><br><span class="line">        backTracking(i + <span class="number">1</span>, j, board, word, visited, pos + <span class="number">1</span>);</span><br><span class="line">        backTracking(i, j - <span class="number">1</span>, board, word, visited, pos + <span class="number">1</span>);</span><br><span class="line">        backTracking(i, j + <span class="number">1</span>, board, word, visited, pos + <span class="number">1</span>);</span><br><span class="line">        visited[i][j] = <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="51-N皇后-回溯法-hard"><a href="#51-N皇后-回溯法-hard" class="headerlink" title="51 N皇后(回溯法) hard"></a>51 N皇后(回溯法) hard</h2><p>久闻的经典题！题目要求就是任何两个皇后都不能在同一行、同一列以及同一条斜线上。思考：斜线怎么判断？</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//这是别人用java改写labuladong的C++版本，感觉非常好理解。</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    List&lt;List&lt;String&gt;&gt; res = <span class="keyword">new</span> ArrayList&lt;&gt;();<span class="comment">//这里是全局哦</span></span><br><span class="line">    <span class="keyword">public</span> List&lt;List&lt;String&gt;&gt; solveNQueens(<span class="keyword">int</span> n) &#123;</span><br><span class="line">        <span class="keyword">char</span>[][] board = <span class="keyword">new</span> <span class="keyword">char</span>[n][n];</span><br><span class="line">        <span class="comment">//初始化棋盘</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">char</span>[] c : board) &#123;</span><br><span class="line">            Arrays.fill(c, <span class="string">&#x27;.&#x27;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        backtracking(board, <span class="number">0</span>);</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">backtracking</span><span class="params">(<span class="keyword">char</span>[][] board, <span class="keyword">int</span> row)</span> </span>&#123;</span><br><span class="line">        <span class="comment">//每一行都成功放置好了皇后，注意这里不是board.length - 1，我的理解是，首先你row进来是检查能不能放，所以最后全部放好后，row会+1,，这时候才判断已经全部能放。</span></span><br><span class="line">        <span class="keyword">if</span> (row == board.length) &#123;</span><br><span class="line">            res.add(charToList(board));</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">int</span> n = board[row].length;<span class="comment">//其实有没有row都一样，都是N*N棋盘。</span></span><br><span class="line">        <span class="comment">//对列进行遍历</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> col = <span class="number">0</span>; col &lt; n; col++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (!isValid(board, row, col)) &#123;<span class="comment">//判断能不能放皇后，不能放就跳过</span></span><br><span class="line">                <span class="keyword">continue</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            board[row][col] = <span class="string">&#x27;Q&#x27;</span>;<span class="comment">//能放就置为Q</span></span><br><span class="line">            backtracking(board, row + <span class="number">1</span>);<span class="comment">//对下一行进行操作</span></span><br><span class="line">            board[row][col] = <span class="string">&#x27;.&#x27;</span>;<span class="comment">//回溯法关键，也就是恢复原来标记</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isValid</span><span class="params">(<span class="keyword">char</span>[][] board, <span class="keyword">int</span> row, <span class="keyword">int</span> col)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> n = board.length;</span><br><span class="line">        <span class="comment">//判断列是否能放皇后</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (board[i][col] == <span class="string">&#x27;Q&#x27;</span>) &#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//判断右上方有没有皇后冲突</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = row - <span class="number">1</span>, j = col + <span class="number">1</span>; i &gt;= <span class="number">0</span> &amp;&amp; j &lt; n; i--, j++) &#123;<span class="comment">//先跳到上一行，列也要加一行，依次类推，注意边界！</span></span><br><span class="line">            <span class="keyword">if</span> (board[i][j] == <span class="string">&#x27;Q&#x27;</span>) &#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//判断左上方有没有皇后冲突</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = row - <span class="number">1</span>, j = col - <span class="number">1</span>; i &gt;= <span class="number">0</span> &amp;&amp; j &gt;=<span class="number">0</span>; i--, j--) &#123;<span class="comment">//先跳到上一行，列也要减一行，依次类推，注意边界！</span></span><br><span class="line">            <span class="keyword">if</span> (board[i][j] == <span class="string">&#x27;Q&#x27;</span>) &#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">        <span class="comment">//这里为什么不进行左下方和右下方进行判断？因为是一行行进行放，这时候左下和右下必定没有呀</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> List <span class="title">charToList</span><span class="params">(<span class="keyword">char</span>[][] board)</span> </span>&#123;</span><br><span class="line">        List&lt;String&gt; list = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">char</span>[] c : board) &#123;</span><br><span class="line">            list.add(String.copyValueOf(c));</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> list;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">本题有很多需要学习的写法</span><br><span class="line"><span class="number">1.</span><span class="keyword">for</span> (<span class="keyword">char</span>[] c : board) &#123;</span><br><span class="line">    System.out.print(<span class="string">&quot;1&quot;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">本句输出是<span class="number">1111</span>，也就是说，对于Arrays.fill(c, <span class="string">&#x27;.&#x27;</span>)每次操作，都是[., ., ., .]，一次性把每行的<span class="number">4</span>个位置都填充上，然后一共操作<span class="number">4</span>次而不是<span class="number">16</span>次。</span><br><span class="line"></span><br><span class="line"><span class="number">2.</span>Arrays.fill(c, <span class="string">&#x27;.&#x27;</span>);<span class="comment">//初始化棋盘这里</span></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>;i&lt;n;i++)&#123;</span><br><span class="line">    System.out.print(Arrays.toString(board[i]));</span><br><span class="line">&#125;</span><br><span class="line">输出结果是：</span><br><span class="line">[., ., ., .][., ., ., .][., ., ., .][., ., ., .]</span><br><span class="line"></span><br><span class="line"><span class="number">3.</span><span class="keyword">for</span> (<span class="keyword">char</span>[] c : board) &#123;</span><br><span class="line">            list.add(String.copyValueOf(c));</span><br><span class="line">&#125;</span><br><span class="line">首先为什么要这么操作，因为输入是一个二维数组来的，最后的输出要符合题目输出，把每一个一维数组加到list中！</span><br><span class="line">这一段的操作是这样看，首先是输入一个已经摆放好皇后的棋盘</span><br><span class="line">String.copyValueOf是返回字符串</span><br><span class="line">然后<span class="keyword">char</span> c是提取每一行出来，比如第一行.Q..然后add到list中，最后扫描完所有行list是这样[.Q.., ...Q, Q..., ..Q.]，然后再res.add进去。</span><br></pre></td></tr></table></figure>
<h2 id="934-最短的桥-DFS-BFS-medium"><a href="#934-最短的桥-DFS-BFS-medium" class="headerlink" title="934 最短的桥(DFS+BFS) medium"></a>934 最短的桥(DFS+BFS) medium</h2><p>一般广度优先遍历用于求最短路径或者可达性问题。本题实际上就是求两个岛屿之间的最短距离，先任意找到一个岛，然后用广度优先搜索寻找和另外一个岛屿的最短距离。结合了书和<a target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/shortest-bridge/solution/java-bfsyu-dfsshi-yong-by-ppppjqute-jvwv/">该作者</a>的想法。做完这个题其实还是有点不理解，因为首先是找到了第一个岛后就break掉了，那怎么知道其他岛与其他岛会不会有更小的距离呢？经过我的探索，终于知道了，因为题目样例中有且仅有两个岛！！！！！！不会出现第三个岛！！！！务必知道挨着的1是属于一个岛！！！</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br></pre></td><td class="code"><pre><span class="line">有个地方需要注意，两个陆地挨着的属于一个岛。比如[[<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>],[<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>],[<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>]]这种情况是一个岛，当然了，这个用例是不能被输入的，因为必须要有两个岛。还有这个题返回的是必须翻转<span class="number">0</span>的数目。</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">shortestBridge</span><span class="params">(<span class="keyword">int</span>[][] grid)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span>[][] direction = <span class="keyword">new</span> <span class="keyword">int</span>[][]&#123;&#123;<span class="number">1</span>, <span class="number">0</span>&#125;, &#123;-<span class="number">1</span>, <span class="number">0</span>&#125;, &#123;<span class="number">0</span>, <span class="number">1</span>&#125;, &#123;<span class="number">0</span>, -<span class="number">1</span>&#125;&#125;;<span class="comment">//四个方向坐标</span></span><br><span class="line">        <span class="keyword">int</span> n = grid.length;</span><br><span class="line">        <span class="keyword">int</span> m = grid[<span class="number">0</span>].length;</span><br><span class="line">        <span class="keyword">int</span> ans = -<span class="number">1</span>;<span class="comment">//初始化距离，这里为什么要设置-1而不是0，因为一进入下面的while后首先是搜索以自己为目标的四周，所以第一次进入while，先ans++，这样就初始化了为0，然后再从我自己扩散出去，而且循环里面是找到了下一个陆地直接返回ans，没有进行加加，一开始提前了ans++。</span></span><br><span class="line">        <span class="keyword">boolean</span> flag = <span class="keyword">false</span>;</span><br><span class="line">        Deque&lt;<span class="keyword">int</span> []&gt; point = <span class="keyword">new</span> ArrayDeque&lt;&gt;();<span class="comment">//队列记录坐标</span></span><br><span class="line">        <span class="comment">//dfs寻找第一个岛，并把这个岛全部标记为2，注意想象一下周围一圈都是1，表达是一个岛，会把这一圈的1都标记为2</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (flag == <span class="keyword">true</span>) <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt; m ; j++) &#123;</span><br><span class="line">                <span class="keyword">if</span> (grid[i][j] == <span class="number">1</span>) &#123;</span><br><span class="line">                    dfs(grid, point, i, j); </span><br><span class="line">                    flag = <span class="keyword">true</span>;<span class="comment">//代表找到了岛</span></span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//进行广度搜索，看多少层能到下一个陆地</span></span><br><span class="line">        <span class="keyword">while</span> (!point.isEmpty()) &#123;<span class="comment">//point不为空</span></span><br><span class="line">            <span class="keyword">int</span> size = point.size();</span><br><span class="line">            ans++;<span class="comment">//每扩散一次，距离加1</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; size; i++) &#123;<span class="comment">//依次对标记过为2的岛进行操作</span></span><br><span class="line">                <span class="comment">//System.out.print(&quot;hello  &quot;+ ans+&quot;   &quot;+&quot;  &quot;);</span></span><br><span class="line">                <span class="keyword">int</span>[] node = point.poll();<span class="comment">//取出队列中第一个岛的坐标，并删除队列中该坐标</span></span><br><span class="line">                <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt; <span class="number">4</span>; j++) &#123;<span class="comment">//上下左右寻找</span></span><br><span class="line">                    <span class="keyword">int</span> next_x = node[<span class="number">0</span>] + direction[j][<span class="number">0</span>];</span><br><span class="line">                    <span class="keyword">int</span> next_y = node[<span class="number">1</span>] + direction[j][<span class="number">1</span>];</span><br><span class="line">                    <span class="keyword">if</span>(next_x &lt; <span class="number">0</span> || next_x &gt;= grid.length || next_y &lt; <span class="number">0</span> || next_y &gt;= grid[<span class="number">0</span>].length || grid[next_x][next_y] == <span class="number">2</span>) &#123;<span class="comment">//判断：不能超边界以及不能是访问过的陆地</span></span><br><span class="line">                        <span class="keyword">continue</span>;</span><br><span class="line">                    &#125;</span><br><span class="line">                    <span class="keyword">if</span> (grid[next_x][next_y] == <span class="number">1</span>) &#123;<span class="comment">//找到下一个岛</span></span><br><span class="line">                        <span class="keyword">return</span> ans;</span><br><span class="line">                    &#125;</span><br><span class="line">                    grid[next_x][next_y] = <span class="number">2</span>;<span class="comment">//走过的地方要标记为2(这些地方可能是水哦)</span></span><br><span class="line">                    point.add(<span class="keyword">new</span> <span class="keyword">int</span>[]&#123;next_x, next_y&#125;);<span class="comment">//把这些坐标都记录起来</span></span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> ans;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span>[][] grid, Deque&lt;<span class="keyword">int</span> []&gt; point, <span class="keyword">int</span> i, <span class="keyword">int</span> j)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (i &lt; <span class="number">0</span> || i &gt;= grid.length || j &lt; <span class="number">0</span> || j &gt;= grid[<span class="number">0</span>].length || grid[i][j] == <span class="number">2</span> || grid[i][j] != <span class="number">1</span>) &#123;<span class="comment">//边界判断以及走过的地方不搜索还有不是陆地的不搜索</span></span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        grid[i][j] = <span class="number">2</span>;</span><br><span class="line">        point.add(<span class="keyword">new</span> <span class="keyword">int</span>[]&#123;i, j&#125;);</span><br><span class="line">        dfs(grid, point, i - <span class="number">1</span>, j);</span><br><span class="line">        dfs(grid, point, i + <span class="number">1</span>, j);</span><br><span class="line">        dfs(grid, point, i, j - <span class="number">1</span>);</span><br><span class="line">        dfs(grid, point, i, j + <span class="number">1</span>);</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;举个例子：</span><br><span class="line">现在两个岛是这样的，就是一个L型和中间一块小岛</span><br><span class="line">[[<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>],[<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>],[<span class="number">1</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>],[<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>],[<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>]]</span><br><span class="line">下面最左边的<span class="number">9</span>和<span class="number">7</span>代表队列中的元素个数，hello具体位置在上面代码看，表达进入<span class="keyword">for</span>循环，hello右边是ans的大小，最右边是取出来的坐标。可以看到，先把L型岛坐标全部放进队列，然后一个个坐标取出来再再看四周(并且也把四周的点加入到队列)，第一轮发现是没有碰到陆地的，所以到了第二轮，第二轮是<span class="number">7</span>因为L型右边的坐标围起来是<span class="number">7</span>个，然后开始继续找，到了<span class="number">2</span>,<span class="number">1</span>坐标，可以知道右边一个位置是<span class="number">1</span>，这时候已经找到了，返回ans。</span><br><span class="line"><span class="number">9</span>  hello  <span class="number">0</span>     <span class="number">0</span> <span class="number">0</span></span><br><span class="line">hello  <span class="number">0</span>     <span class="number">1</span> <span class="number">0</span></span><br><span class="line">hello  <span class="number">0</span>     <span class="number">2</span> <span class="number">0</span></span><br><span class="line">hello  <span class="number">0</span>     <span class="number">3</span> <span class="number">0</span></span><br><span class="line">hello  <span class="number">0</span>     <span class="number">4</span> <span class="number">0</span></span><br><span class="line">hello  <span class="number">0</span>     <span class="number">4</span> <span class="number">1</span></span><br><span class="line">hello  <span class="number">0</span>     <span class="number">4</span> <span class="number">2</span></span><br><span class="line">hello  <span class="number">0</span>     <span class="number">4</span> <span class="number">3</span></span><br><span class="line">hello  <span class="number">0</span>     <span class="number">4</span> <span class="number">4</span></span><br><span class="line"><span class="number">7</span>  hello  <span class="number">1</span>     <span class="number">0</span> <span class="number">1</span></span><br><span class="line">hello  <span class="number">1</span>     <span class="number">1</span> <span class="number">1</span></span><br><span class="line">hello  <span class="number">1</span>     <span class="number">2</span> <span class="number">1</span></span><br></pre></td></tr></table></figure>
<h2 id="126-单词接龙2-回溯-BFS-hard"><a href="#126-单词接龙2-回溯-BFS-hard" class="headerlink" title="126 单词接龙2(回溯+BFS) hard"></a>126 单词接龙2(回溯+BFS) hard</h2><p>单词只差一个字母的可以连接成节点，思考如何去判断只相差一个字母？回溯也就是深度优先搜索的一个应用，用于找出所有情况，BFS也就是找到最短路径，合起来就是找出所有的最短路径。这个题和上一个题差不多。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//官方的解答，学到就是我的🤓</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="keyword">public</span> List&lt;List&lt;String&gt;&gt; findLadders(String beginWord, String endWord, List&lt;String&gt; wordList) &#123;</span><br><span class="line">        List&lt;List&lt;String&gt;&gt; res = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">        Set&lt;String&gt; dict = <span class="keyword">new</span> HashSet&lt;&gt;(wordList);<span class="comment">// 因为需要快速判断扩展出的单词是否在 wordList 里，因此需要将 wordList 存入哈希表，这里命名为「字典」</span></span><br><span class="line">        <span class="keyword">if</span> (!dict.contains(endWord)) &#123;<span class="comment">// 特殊用例判断</span></span><br><span class="line">            <span class="keyword">return</span> res;</span><br><span class="line">        &#125;</span><br><span class="line">        dict.remove(beginWord);<span class="comment">//把beginword在字典里删除掉</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">// 第 1 步：广度优先遍历建图</span></span><br><span class="line">        <span class="comment">// 记录扩展出的单词是在第几次扩展的时候得到的，key：单词，value：在广度优先遍历的第几层</span></span><br><span class="line">        Map&lt;String, Integer&gt; steps = <span class="keyword">new</span> HashMap&lt;&gt;();</span><br><span class="line">        steps.put(beginWord, <span class="number">0</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 记录了单词是从哪些单词扩展而来，key：单词，value：单词列表，这些单词可以变换到 key ，它们是一对多关系</span></span><br><span class="line">        Map&lt;String, List&lt;String&gt;&gt; from = <span class="keyword">new</span> HashMap&lt;&gt;();</span><br><span class="line">        <span class="keyword">int</span> step = <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">boolean</span> found = <span class="keyword">false</span>;</span><br><span class="line">        <span class="keyword">int</span> wordlen = beginWord.length();<span class="comment">//记录单词的长度，以便于对每个字符进行更换</span></span><br><span class="line">        Queue&lt;String&gt; queue = <span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">        queue.offer(beginWord);<span class="comment">//把开始的单词加进去</span></span><br><span class="line"></span><br><span class="line">        <span class="keyword">while</span>(!queue.isEmpty()) &#123;<span class="comment">//不为空就运行</span></span><br><span class="line">            <span class="keyword">int</span> size = queue.size();</span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; size; i++) &#123;<span class="comment">//对queue里面的单词依次操作</span></span><br><span class="line">                String currword = queue.poll();<span class="comment">//先取出queue第一个单词</span></span><br><span class="line">                <span class="keyword">char</span>[] chararray = currword.toCharArray();<span class="comment">//将字符串转换为字符数组</span></span><br><span class="line">                <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt; wordlen; j++) &#123;<span class="comment">//对每一个位置的字符进行操作</span></span><br><span class="line">                    <span class="keyword">char</span> origin = chararray[j];<span class="comment">//先保存原来的字符，以便后面进行恢复</span></span><br><span class="line">                    <span class="keyword">for</span> (<span class="keyword">char</span> c = <span class="string">&#x27;a&#x27;</span>; c &lt;= <span class="string">&#x27;z&#x27;</span>; c++) &#123;<span class="comment">//每个位置都可以替换26次（包括原来的自己啦）</span></span><br><span class="line">                        chararray[j] = c;<span class="comment">//替换成果</span></span><br><span class="line">                        String nextword = String.valueOf(chararray);<span class="comment">//char数组转成字符串</span></span><br><span class="line">                        <span class="keyword">if</span> (steps.containsKey(nextword) &amp;&amp; step == steps.get(nextword)) &#123;<span class="comment">//初步理解就是，如果大家都在同一个level的词变换，就进行操作添加这个词</span></span><br><span class="line">                            <span class="comment">//System.out.print(&quot;nextword is &quot;+nextword);</span></span><br><span class="line">                            <span class="comment">//System.out.print(&quot;currword is &quot;+currword);</span></span><br><span class="line">                            from.get(nextword).add(currword);<span class="comment">//如果有这个key的记录, 添加新值</span></span><br><span class="line">                            <span class="comment">//System.out.println(&quot;from is a  &quot;+from);</span></span><br><span class="line">                        &#125;</span><br><span class="line">                        <span class="keyword">if</span> (!dict.contains(nextword)) &#123;<span class="comment">//dict中不存在这个单词就跳过</span></span><br><span class="line">                            <span class="keyword">continue</span>;</span><br><span class="line">                        &#125;</span><br><span class="line"></span><br><span class="line">                        <span class="comment">//下面这两句思考一下！！！！！</span></span><br><span class="line">                        dict.remove(nextword);<span class="comment">//如果从一个单词扩展出来的单词以前遍历过，距离一定更远，为了避免搜索到已经遍历到，且距离更远的单词，需要将它从 dict 中删除</span></span><br><span class="line">                        queue.add(nextword); <span class="comment">// 那么这一层扩展出的单词进入队列</span></span><br><span class="line">                        <span class="comment">// 记录 nextword 从 currWord 而来</span></span><br><span class="line">                        from.putIfAbsent(nextword, <span class="keyword">new</span> ArrayList&lt;&gt;());</span><br><span class="line">                        from.get(nextword).add(currword);</span><br><span class="line">                        <span class="comment">// 记录 nextword 的 step</span></span><br><span class="line">                        steps.put(nextword, step);</span><br><span class="line">                        <span class="keyword">if</span> (nextword.equals(endWord)) &#123;<span class="comment">//等于最后一个单词就把found设置为true</span></span><br><span class="line">                            found = <span class="keyword">true</span>;</span><br><span class="line">                        &#125;</span><br><span class="line">                        <span class="comment">//System.out.println(&quot;dict is &quot;+dict);</span></span><br><span class="line">                        <span class="comment">//System.out.println(&quot;queue is &quot;+queue);</span></span><br><span class="line">                        <span class="comment">//System.out.println(&quot;from is &quot;+from);</span></span><br><span class="line">                        <span class="comment">//System.out.println(&quot;steps is &quot;+steps);</span></span><br><span class="line">                    &#125;</span><br><span class="line">                    chararray[j] = origin;<span class="comment">//还原单词</span></span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            step++;<span class="comment">//level加1</span></span><br><span class="line">            <span class="keyword">if</span> (found) &#123;<span class="comment">//找到就打断程序</span></span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 第 2 步：深度优先遍历找到所有解，从 endWord 恢复到 beginWord ，所以每次尝试操作 path 列表的头部</span></span><br><span class="line">        <span class="keyword">if</span> (found) &#123;</span><br><span class="line">            Deque&lt;String&gt; path = <span class="keyword">new</span> ArrayDeque&lt;&gt;();</span><br><span class="line">            path.add(endWord);</span><br><span class="line">            backtracking(from, path ,beginWord ,endWord ,res);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//注意这个回溯反着来找，从尾巴一直寻找到最开始，就是根据from记录的信息来寻找</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">backtracking</span><span class="params">(Map&lt;String, List&lt;String&gt;&gt; from, Deque&lt;String&gt; path, String beginWord, String cur, List&lt;List&lt;String&gt;&gt; res)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (cur.equals(beginWord)) &#123;</span><br><span class="line">            res.add(<span class="keyword">new</span> ArrayList&lt;&gt;(path));</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> (String preucrsor : from.get(cur)) &#123;</span><br><span class="line">            path.addFirst(preucrsor);</span><br><span class="line">            backtracking(from, path, beginWord, preucrsor, res);</span><br><span class="line">            path.removeFirst();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">老规矩，看不懂怎么运行就一步步打印出来</span></span><br><span class="line"><span class="comment">dict is [lot, log, dot, cog, dog]</span></span><br><span class="line"><span class="comment">queue is [hot]</span></span><br><span class="line"><span class="comment">from is &#123;hot=[hit]&#125;</span></span><br><span class="line"><span class="comment">steps is &#123;hit=0, hot=1&#125;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">dict is [lot, log, cog, dog]</span></span><br><span class="line"><span class="comment">queue is [dot]</span></span><br><span class="line"><span class="comment">from is &#123;dot=[hot], hot=[hit]&#125;</span></span><br><span class="line"><span class="comment">steps is &#123;hit=0, dot=2, hot=1&#125;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">dict is [log, cog, dog]</span></span><br><span class="line"><span class="comment">queue is [dot, lot]</span></span><br><span class="line"><span class="comment">from is &#123;lot=[hot], dot=[hot], hot=[hit]&#125;</span></span><br><span class="line"><span class="comment">steps is &#123;lot=2, hit=0, dot=2, hot=1&#125;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">dict is [log, cog]</span></span><br><span class="line"><span class="comment">queue is [lot, dog]</span></span><br><span class="line"><span class="comment">from is &#123;lot=[hot], dot=[hot], hot=[hit], dog=[dot]&#125;</span></span><br><span class="line"><span class="comment">steps is &#123;lot=2, hit=0, dot=2, hot=1, dog=3&#125;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">dict is [cog]</span></span><br><span class="line"><span class="comment">queue is [dog, log]</span></span><br><span class="line"><span class="comment">from is &#123;lot=[hot], log=[lot], dot=[hot], hot=[hit], dog=[dot]&#125;</span></span><br><span class="line"><span class="comment">steps is &#123;lot=2, hit=0, log=3, dot=2, hot=1, dog=3&#125;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">dict is []</span></span><br><span class="line"><span class="comment">queue is [log, cog]</span></span><br><span class="line"><span class="comment">from is &#123;lot=[hot], log=[lot], dot=[hot], cog=[dog], hot=[hit], dog=[dot]&#125;</span></span><br><span class="line"><span class="comment">steps is &#123;lot=2, hit=0, log=3, dot=2, cog=4, hot=1, dog=3&#125;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">//这个是第一个if语句中的输出，对于这个例子，一共才运行了一次，仔细观察cog这个值多了一个log</span></span><br><span class="line"><span class="comment">nextword is cog</span></span><br><span class="line"><span class="comment">curword is log</span></span><br><span class="line"><span class="comment">from is a  &#123;lot=[hot], log=[lot], dot=[hot], cog=[dog, log], hot=[hit], dog=[dot]&#125;</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">map和hashmap区别?</span><br><span class="line">queue和Deque区别?</span><br><span class="line">add offer等操作区别?</span><br><span class="line">contains和containskey区别?</span><br><span class="line">put和putIfAbsent区别：put在放入数据时，如果放入数据的key已经存在与Map中，最后放入的数据会覆盖之前存在的数据，而putIfAbsent在放入数据时，如果存在重复的key，那么putIfAbsent不会放入值。</span><br><span class="line">测试的时候发现下面两种写法都是可以的，可以百度下他们的不同。</span><br><span class="line">Deque&lt;String&gt; path = <span class="keyword">new</span> ArrayDeque&lt;&gt;();</span><br><span class="line">Deque&lt;String&gt; path = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br></pre></td></tr></table></figure>
    </div>

    
    
    

    <footer class="post-footer">
          

<div class="post-copyright">
<ul>
  <li class="post-copyright-author">
      <strong>本文作者： </strong>小陈同学
  </li>
  <li class="post-copyright-link">
      <strong>本文链接：</strong>
      <a href="https://chenwingsing.github.io/2021/09/20/LeetCode-JAVA/" title="LeetCode-JAVA">https://chenwingsing.github.io/2021/09/20/LeetCode-JAVA/</a>
  </li>
  <li class="post-copyright-license">
    <strong>版权声明： </strong>本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" rel="noopener" target="_blank"><i class="fab fa-fw fa-creative-commons"></i>BY-NC-SA</a> 许可协议。转载请注明出处！
  </li>
</ul>
</div>

          <div class="post-tags">
              <a href="/tags/Leetcode/" rel="tag"><i class="fa fa-tag"></i> Leetcode</a>
          </div>

        

          <div class="post-nav">
            <div class="post-nav-item">
                <a href="/2021/04/02/Pytorch-Tips/" rel="prev" title="Pytorch Tips">
                  <i class="fa fa-chevron-left"></i> Pytorch Tips
                </a>
            </div>
            <div class="post-nav-item">
                <a href="/2021/12/04/Github%E7%AC%94%E8%AE%B0/" rel="next" title="Github笔记">
                  Github笔记 <i class="fa fa-chevron-right"></i>
                </a>
            </div>
          </div>
    </footer>
  </article>
</div>






    <div class="comments" id="valine-comments"></div>
</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">


<div class="copyright">
  &copy; 
  <span itemprop="copyrightYear">2022</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">小陈同学呀</span>
</div>
<div class="wordcount">
  <span class="post-meta-item">
    <span class="post-meta-item-icon">
      <i class="fa fa-chart-line"></i>
    </span>
    <span title="站点总字数">83k</span>
  </span>
  <span class="post-meta-item">
    <span class="post-meta-item-icon">
      <i class="fa fa-coffee"></i>
    </span>
    <span title="站点阅读时长">1:15</span>
  </span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/mist/" rel="noopener" target="_blank">NexT.Mist</a> 强力驱动
  </div>

    </div>
  </footer>

  
  <script src="https://cdn.jsdelivr.net/npm/animejs@3.2.1/lib/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/schemes/muse.js"></script><script src="/js/next-boot.js"></script>

  





  






<script class="next-config" data-name="valine" type="application/json">{"enable":true,"appId":"5kJQPbqUaVp4R03CwsPV0PEx-gzGzoHsz","appKey":"alfUMJjgEoEg26GBrn4BfzwM","serverURLs":"https://5kjqpbqu.lc-cn-n1-shared.com","placeholder":"上面的信息均为选填，快来留下你的脚印😎 Tips：此匿名评论系统支持Gravatar以及QQ头像(昵称输入您的QQ号)","avatar":"mp","meta":["nick","mail","link"],"pageSize":10,"lang":null,"visitor":false,"comment_count":false,"recordIP":true,"enableQQ":true,"requiredFields":[],"el":"#valine-comments","path":"/2021/09/20/LeetCode-JAVA/"}</script>
<script>
document.addEventListener('page:loaded', () => {
  NexT.utils.loadComments(CONFIG.valine.el)
    .then(() => NexT.utils.getScript(
      'https://cdn.jsdelivr.net/npm/valine@1.4.14/dist/Valine.min.js',
      { condition: window.Valine }
    ))
    .then(() => {
      new Valine(CONFIG.valine);
    });
});
</script>

</body>
</html>
